# Internationalization We want the official Bluesky app to be supported in as many languages as possible. If you want to help us translate the app, please open a PR or issue on the [Bluesky app repo on GitHub](https://github.com/bluesky-social/social-app) ## Tools We are using Lingui to manage translations. You can find the documentation [here](https://lingui.dev/). ### Adding new strings When adding a new string, do it as follows: ```jsx // Before import { Text } from "react-native"; Hello World ``` ```jsx // After import { Text } from "react-native"; import { Trans } from "@lingui/macro"; Hello World ``` The `` macro will extract the string and add it to the catalog. It is not really a component, but a macro. Further reading [here](https://lingui.dev/ref/macro.html) However sometimes you will run into this case: ```jsx // Before import { Text } from "react-native"; const text = "Hello World"; {text} ``` In this case, you cannot use the `useLingui()` hook: ```jsx import { msg } from "@lingui/macro"; import { useLingui } from "@lingui/react"; const { _ } = useLingui(); return {text} ``` If you want to do this outside of a React component, you can use the `t` macro instead (note: this won't react to changes if the locale is switched dynamically within the app): ```jsx import { t } from "@lingui/macro"; const text = t`Hello World`; ``` We can then run `yarn intl:extract` to update the catalog in `src/locale/locales/{locale}/messages.po`. This will add the new string to the catalog. We can then run `yarn intl:compile` to update the translation files in `src/locale/locales/{locale}/messages.js`. This will add the new string to the translation files. The configuration for translations is defined in `lingui.config.js` So the workflow is as follows: 1. Wrap messages in Trans macro 2. Run `yarn intl:extract` command to generate message catalogs 3. Translate message catalogs (send them to translators usually) 4. Run `yarn intl:compile` to create runtime catalogs 5. Load runtime catalog 6. Enjoy translated app! ### Common pitfalls These pitfalls are memoization pitfalls that will cause the components to not re-render when the locale is changed -- causing stale translations to be shown. ```jsx import { msg } from "@lingui/macro"; import { i18n } from "@lingui/core"; const welcomeMessage = msg`Welcome!`; // ❌ Bad! This code won't work export function Welcome() { const buggyWelcome = useMemo(() => { return i18n._(welcomeMessage); }, []); return
{buggyWelcome}
; } // ❌ Bad! This code won't work either because the reference to i18n does not change export function Welcome() { const { i18n } = useLingui(); const buggyWelcome = useMemo(() => { return i18n._(welcomeMessage); }, [i18n]); return
{buggyWelcome}
; } // ✅ Good! `useMemo` has i18n context in the dependency export function Welcome() { const linguiCtx = useLingui(); const welcome = useMemo(() => { return linguiCtx.i18n._(welcomeMessage); }, [linguiCtx]); return
{welcome}
; } // 🤩 Better! `useMemo` consumes the `_` function from the Lingui context export function Welcome() { const { _ } = useLingui(); const welcome = useMemo(() => { return _(welcomeMessage); }, [_]); return
{welcome}
; } ```