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.