Skip to content

Preferred languages ​

Allows tracking user's preferred languages with Events and Stores.

Usage ​

All you need to do is to create an integration by calling trackPreferredLanguages with an integration options:

  • setup: after this Event all listeners will be installed, and the integration will be ready to use; it is required because it is better to use explicit initialization Event in the application.
  • teardown?: after this Event all listeners will be removed, and the integration will be ready to be destroyed.
ts
import { trackPreferredLanguages } from '@withease/web-api';

const { $language, $languages, languageChanged } = trackPreferredLanguages({
  setup: appStarted,
});

Returns an object with:

  • $language: Store with user's preferred language
  • $languages: Store with array of user's preferred languages sorted by priority
  • languageChanged: Event that fires on preferred language change

TIP

It supports @@trigger protocol. Since it allows firing only one Event trackPreferredLanguages triggers languageChanged as a fired in case of @@trigger protocol.

ts
import { trackPreferredLanguages } from '@withease/web-api';

somethingExpectsTrigger(trackPreferredLanguages);

Live demo ​

Let us show you a live demo of how it works. The following demo displays a $languages value. Change your system or browser language to see how it works.

<script setup>
import { trackPreferredLanguages } from '@withease/web-api';
import { createEvent } from 'effector';
import { useUnit } from 'effector-vue/composition';
import { onMounted } from 'vue';

const appStarted = createEvent();

const { $languages } = trackPreferredLanguages({ setup: appStarted });

const languages = useUnit($languages);

onMounted(appStarted);
</script>

<template>
  <ol>
    <li v-for="lang in languages">{{ lang }}</li>
  </ol>
</template>

Service-side rendering (SSR) ​

It uses browser's APIs like window.addEventListener and navigator.languages under the hood, which are not available in server-side environment. However, it is possible to use it while SSR by passing header Accept-Language from the user's request to the special Store trackPreferredLanguages.$acceptLanguageHeader while fork in the server-side environment. Every server-side framework has its own way to do it, there are some examples:

Fastify
ts
// server.ts
import { trackPreferredLanguages } from '@withease/web-api';

fastify.get('*', {
  async handler(request, reply) {
    const scope = fork({
      values: [
        [
          trackPreferredLanguages.$acceptLanguageHeader,
          request.headers['Accept-Language'],
        ],
      ],
    });

    await allSettled(appStarted);

    // render HTML and return it

    return reply.send(html);
  },
});
Express
ts
// server.ts
import { trackPreferredLanguages } from '@withease/web-api';

app.get('*', (req, res) => {
  const scope = fork({
    values: [
      [
        trackPreferredLanguages.$acceptLanguageHeader,
        req.get('Accept-Language'),
      ],
    ],
  });

  allSettled(appStarted)
    .then(() => {
      // render HTML and return it
      return html;
    })
    .then((html) => {
      res.send(html);
    });
});
NestJS
ts
// server.ts
import { trackPreferredLanguages } from '@withease/web-api';

@Controller()
export class SSRController {
  @Get('*')
  async render(@Headers('Accept-Language') acceptLanguageHeader: string) {
    const scope = fork({
      values: [
        [trackPreferredLanguages.$acceptLanguageHeader, acceptLanguageHeader],
      ],
    });

    await allSettled(appStarted);

    // render HTML and return it

    return html;
  }
}

Released under the MIT License.