# i18n

sdk.i18n.locale() gives the locale the host asked for, a lowercase BCP 47 tag; on('change') follows a switch while the game runs.

## `i18n.locale(): string`

A BCP 47 tag in lowercase: `en`, `fr`, `pt-br`. From the host when it has one (filudi.com passes the
site's locale; CrazyGames exposes `user.systemInfo.locale`; Playgama `bridge.platform.language`; Poki has
none), else `navigator.language`, else `en`. `init({ locale })` overrides all of it. Throws before
`init()` resolves.

<CodePanel title="Pick the strings">
  <Fragment slot="javascript">
    ```js
    const strings = { en, fr };
    let t = strings[sdk.i18n.locale().split('-')[0]] ?? en;
    ```

  </Fragment>
  <Fragment slot="typescript">
    ```ts
    const strings: Record<string, Strings> = { en, fr };
    let t: Strings = strings[sdk.i18n.locale().split('-')[0] ?? 'en'] ?? en;
    ```

  </Fragment>
</CodePanel>

## `i18n.on('change', listener): Off`

Fires when the host switches locale while the game runs; filudi.com does when the player changes the site
language. The listener gets the new tag. `sdk.on('locale', listener)` is the same event under the host
events.

<CodePanel title="Redraw on a switch">
  <Fragment slot="javascript">
    ```js
    sdk.i18n.on('change', (locale) => {
      t = strings[locale.split('-')[0]] ?? en;
      redrawMenus();
    });
    ```

  </Fragment>
  <Fragment slot="typescript">
    ```ts
    sdk.i18n.on('change', (locale: string) => {
      t = strings[locale.split('-')[0] ?? 'en'] ?? en;
      redrawMenus();
    });
    ```

  </Fragment>
</CodePanel>

## Unavailable cases

None: there is always a locale. A host without one gives the browser's. Which languages filudi.com runs
in, and what to translate first, is in [localization](/docs/games/localization/).
