@beeanco/intl

A modern internationalization framework built to be used in performant progressive web apps

Installation

With node.js installed, use npm to install this package and its peer dependencies:

npm install @beeanco/intl svelte

Please note that this module is currently under development. The API may change soon (we'll follow semver, of course) and the documentation may be incomplete. We'll improve this library over time so feel free to raise an issue if you're missing any essential features.

Usage

How to setup internationalization in a svelte or sapper app that is built with rollup.

Installation

First of all, install the @beeanco/intl package:

npm install --save-dev @beeanco/intl

Setup rollup

First of all, you need to add the rollup-plugin to your rollup.config.js:

// rollup.config.js

import intl from '@beeanco/intl/rollup-plugin';

export default {
  ...
  plugins: [
    // rollup-plugin-svelte and friends...
    intl({
      locales: ['en', 'de'],
      // If you're using sapper, just uncomment the next line:
      // sapper: true
    }),
  ],
  ...
}

By default, this makes @beeanco/intl search for translation files inside ./src/locales/[locale]/. Use the base, include and exclude options to change this: The base option can be used to specify the localization source directory, include and exclude to restrict input on a per-file basis.

// Use all files inside './src/translations' as translation files
intl({
  base: './src/translations',
});

// Use all files inside './src/translations' ending with .loc.json as translation files, but not './src/translations/nope.loc.json'
intl({
  base: './src/translations',
  include: './src/translations/**/*.loc.json',
  exclude: './src/translations/nope.loc.json',
});

Initialization

Note: This step is different in svelte and sapper apps. It's a lot easier to set it up for a sapper app because you don't need to register translation modules yourself.

In a sapper app

When you use sapper, you can use the @beeanco/intl/sapper module to register all components and setup intl. This needs to be done in both client.js and server.js:

// ./src/server.js

import * as sapper from '@sapper/server';
...
import { setupIntl } from '@beeanco/intl/sapper';

// Setup intl
setupIntl(/* no options required at the moment */);

// Your current server initiaization
polka()
  .use(...)
// ./src/client.js

import * as sapper from '@sapper/app';
import { setupIntl } from '@beeanco/intl/sapper';

// Setup intl
setupIntl(/* no options required at the moment */);

// Your current app initiaization
sapper.start({
  target: document.querySelector('#sapper'),
});

In a general svelte app

Next, you need to initialize the module in your app, e.g. in your app entry file (probably main.js or index.js):

// ./src/main.js

import { init, register } from '@beeanco/intl';

// Register localization modules
register('index', {
  en: () => import('./locales/en/index.json'),
  de: () => import('./locales/de/index.json'),
});

// Initialize intl
init({
  locales: ['en', 'de'],
});

// The rest of your app initialization...
const app = new App();

Adding translations

Next, you'll want to add some translations, to test it:

// ./src/locales/en/index.json
{
  "helloUserYouHaveNewMessages": "Hello {name}, you have {count, plural, \n=0 {no new messages}\none {# new message}\nother {# new messages}\n}."
}
// ./src/locales/de/index.json
{
  "helloUserYouHaveNewMessages": "Hallo {name}, du hast {count, plural, \n=0 {keine neue Nachrichten}\none {# neue Nachricht}\nother {# neue Nachrichten}\n}."
}

We use the ICU message format for these templates

Loading translations

Use the loadTranslations and useTranslations methods of @beeanco/intl to load translations, e.g. in layout component:

In a sapper app

<!-- ./src/routes/__layout.svelte -->

<script context="module">
  import { loadTranslations, useTranslations } from '@beeanco/intl';

  export async function preload(page, session) {
    return {
      // Load translations from './src/locales/en/index.json'
      translations: await loadTranslations(
        'en', // The language to load. In most cases you'll want to use e.g. session.locale
        'index' // The file to import
      )
    }
  }
</script>

<script>
  export let translations;
  useTranslations(translations);
</scipt>

Without sapper

FIXME: Add example

Using translations

Finally ๐ŸŽ‰ we can use our translations: Use the t store returned by the intl method to render translated texts:

<!-- ./src/routes/index.svelte -->

<script>
  import { intl } from '@beeanco/intl';

  const { t } = intl();
</script>

<!-- Renders: 'Hello Mike, you have 13 new messages.' -->
<strong>$t.helloUserYouHaveNewMessages({ name: 'Mike', count: 13 })</strong>