Per-app language switching on iOS and Android through the Settings app using the OS's native language switching functionalities for your Expo app.
Expo's Localization module is great, but it doesn't support native language switching on iOS through the Settings app. That might result in you displaying the wrong language to the user. Ever tried to order plane tickets in Spanish because the app decided you totally spoke it? Yeah, not fun.
This plugin creates the necessary files and references in your Xcode and Android Studio projects to support native language switching on iOS and Android. It does not handle the actual translations or fetching the locale in your app. You can use any library you want for that, like i18next for the translation and expo-localization for the locale detection.
Install the package with the Expo CLI:
npx expo install @digitalartlab/expo-plugin-localization
Then add the plugin to your app.json
:
{
"expo": {
"plugins": ["@digitalartlab/expo-plugin-localization"]
}
}
You provide an array of locales that you want to support. The default value is ["en"]
.
{
"expo": {
"plugins": [
[
"@digitalartlab/expo-plugin-localization",
{
"locales": ["en", "nl"]
}
]
]
}
}
This plugin supports all the two-letter language codes (nl
, en
, es
, etc.) Android and iOS support.
Language codes with region and script affixes (nl-NL
, en-GB
, zh-hans-CN
, etc.) are not supported. This is because Android requires different formatting for language codes in various config files. If you really need this, feel free to open an issue or a pull request.
If you use prebuild, you have to use the --clean
flag every time you change the config of this plugin. This is because the plugin can't reliably purge the old values from the config files. And you don't want a language to linger around. That's like Duolingo reminding you to practise long after you gave up!
Not using prebuild? You're good to go!
Expo has a great Localization guide that explains how to fetch the user's current locale. This plugin doesn't change that, so you can use the same code. Behind the scenes, the OS sorts the list of locales to match the user's selection in the Settings app. So, if a user's phone is set to Dutch and the app is set to English, the list of locales will be ["en", "nl"]
instead of ["nl", "en"]
.
Basically: do what you'd already do to detect the user's language and just pick the first value you get.
If you want to explicitely get the list of locales you configured, you can use the getLocales
method. It returns an array of strings with the locales you configured.
import { getLocales } from "@digitalartlab/expo-plugin-localization";
const locales = getLocales();
Important
The getLocales
method returns the locales in the order you configured them. If you want to get the user's preferred locale (to, you know, actually support locale switching), use the Expo Localization module.
Contributions are very welcome! Please take a moment to read our Code of Conduct before contributing.
Run npm install
to install the dependencies.
This project consists of two parts: an Expo module and a config plugin. They work hand in hand.
First, the config plugin adds the necessary files and references to your Xcode and Android Studio projects to support native language switching. The module then optionally exposes the configured locales to your app, if you don't want to use another module like expo-localization
for that, or need the exact locales you configured.
All code for the config plugin is in the /plugin/src
folder. For the module, the code is split between the /src
folder for the TypeScript code and the /ios
and /android
folders for the native code.
The /example
folder contains a barebones Expo app that you can use to test the plugin.
To build the module, run npm run build
. To build the config plugin, run npm run build plugin
.
This repo uses Conventional Commits to automatically generate changelogs. Please make sure your commit messages follow this format. A Husky pre-commit hook is in place to verify this when you commit.
To publish a new version of the module, first merge the PR automatically created by Release Please. This will bump the version number, update CHANGELOG.md
and create a new release tag on GitHub. Then, run npm run publish
to publish the module to NPM. Could this be automated? Yes. Is it? No. Why? ¯\_(ツ)_/¯
This project is licensed under the LGPL-3.0 license. This means you can freely use it in your own projects, also commercial ones. However, if you make changes to this specific library, you have to share those changes with the community. We would definitely welcome a pull request!
Thijmen de Valk (@thijmendevalk)