React Native Quickstart
Easily internationalize your React Native App with gt-react-native
Quick Setup: Try npx gtx-cli@latest for automatic configuration. See the
Setup Wizard guide or use our AI tools
integration.
Installation
Install the gt-react-native and gtx-cli packages:
npm i gt-react-native
npm i -D gtx-cli
cd ios && pod installyarn add gt-react-native
yarn add --dev gtx-cli
cd ios && pod installbun add gt-react-native
bun add --dev gtx-cli
cd ios && pod installpnpm add gt-react-native
pnpm add --save-dev gtx-cli
cd ios && pod installQuick setup
Run npx gtx-cli init to use the wizard to set up your project.
Then follow the instructions for adding the provider to your root layout.
Manual setup
Environment variables
Add to your .env file for development hot-reloading and on-demand translations:
GT_API_KEY="your-dev-api-key"
GT_PROJECT_ID="your-project-id"Dev vs prod keys: Use a gtx-dev- key locally. Use a gtx-api- key in CI/CD if you run gtx-cli translate during deploy.
Never expose GT_API_KEY to the browser or commit it to source control.
Get your free API keys at dash.generaltranslation.com or run:
npx gtx-cli authLoading translations
You can use the loadTranslations function to load translations from a custom source.
This is useful when you need to load translations from a different source, such as a custom API.
export default async function loadTranslations(locale: string) {
try {
const t = await import(`../public/_gt/${locale}.json`);
return t.default;
} catch (error) {
console.warn(`Failed to load translations for locale ${locale}:`, error);
return {};
}
}GTProvider
The GTProvider component provides translation context to client-side components. It manages locale state, translations, and enables the useGT and useTranslations hooks.
Add the GTProvider to your root component:
import { GTProvider } from 'gt-react-native';
import gtConfig from '../gt.config.json';
import loadTranslations from './loadTranslations.ts';
createRoot(document.getElementById('root')!).render(
<GTProvider
config={gtConfig}
loadTranslations={loadTranslations}
projectId='your-project-id'
devApiKey='your-dev-api-key'
>
<App />
</GTProvider>
);Create a gt.config.json file in your project root:
{
"defaultLocale": "en",
"locales": ["fr", "es", "de"]
}Customize the locales for your project. See supported locales for options.
Polyfills
Babel plugin
Because the React Native JS runtime does not automatically polyfill the Intl object, you need to polyfill it manually.
You can either use the either use the babel plugin, or polyfill manually.
For the babel plugin, under entryPointFilePath just specify the entry point of your app (can often be found in the "main" field of your package.json).
import gtPlugin from 'gt-react-native/plugin';
export default function (api) {
return {
plugins: [
[
gtPlugin,
{
locales: [gtConfig.defaultLocale, ...gtConfig.locales],
// for expo - entryPointFilePath: require.resolve('expo-router/entry')
entryPointFilePath: path.resolve(__dirname, 'index.jsx'),
},
],
],
};
}Manual polyfilling
If you run into issues with the babel plugin, you can polyfill manually. You will need to npm install and then polyfill the base imports as well as locale-specific imports.
The following is an example of polyfilling every possible import, but in reality, you may only need a subset of these. For more information see FormatJS's documentation on polyfilling.
// base polyfills:
import '@formatjs/intl-getcanonicallocales/polyfill';
import '@formatjs/intl-locale/polyfill';
import '@formatjs/intl-displaynames/polyfill';
import '@formatjs/intl-listformat/polyfill';
import '@formatjs/intl-pluralrules/polyfill-force'; // https://github.com/formatjs/formatjs/issues/4463
import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/add-all-tz';
// locale polyfills:
// en polyfills
import '@formatjs/intl-displaynames/locale-data/en';
import '@formatjs/intl-listformat/locale-data/en';
import '@formatjs/intl-pluralrules/locale-data/en';
import '@formatjs/intl-numberformat/locale-data/en';
import '@formatjs/intl-relativetimeformat/locale-data/en';
import '@formatjs/intl-datetimeformat/locale-data/en';
// zh polyfills
import '@formatjs/intl-displaynames/locale-data/zh';
import '@formatjs/intl-listformat/locale-data/zh';
import '@formatjs/intl-pluralrules/locale-data/zh';
import '@formatjs/intl-numberformat/locale-data/zh';
import '@formatjs/intl-relativetimeformat/locale-data/zh';
import '@formatjs/intl-datetimeformat/locale-data/zh';Usage
Now you can start internationalizing your content. There are two main approaches:
JSX content with <T>
Wrap JSX elements to translate them using the <T> component:
import { T } from 'gt-react-native';
function Welcome() {
return (
<T>
<h1>Welcome to our app!</h1>
</T>
);
}For dynamic content, use variable components like <Var>:
import { T, Var } from 'gt-react-native';
function Greeting({ user }) {
return (
<T>
<p>
Hello, <Var>{user.name}</Var>!
</p>
</T>
);
}See the guide on using the <T> component for more information.
Plain strings with useGT
For attributes, labels, and plain text using the useGT hook:
import { useGT } from 'gt-react-native';
function ContactForm() {
const gt = useGT();
return (
<input
placeholder={gt('Enter your email')}
aria-label={gt('Email input field')}
/>
);
}See the guide on translating strings for more information.
Testing your app
Test your translations by switching languages:
-
Add a locale selection dropdown using
<LocaleSelector>:import { LocaleSelector } from 'gt-react-native'; function App() { return <LocaleSelector />; } -
Start your dev server:
npm run devyarn run devbun run devpnpm run dev -
Visit your development app and change languages via the locale selection dropdown.
In development, translations happen on-demand (you'll see a brief loading time). In production, translations are pre-generated by the CLI.
Troubleshooting
Deployment
For production, you need to pre-translate content since runtime translation is disabled.
-
Get a production API key from dash.generaltranslation.com.
Production keys begin with
gtx-api-(different from dev keys which start withgtx-dev-). Learn more about environment differences. -
Add to your CI/CD environment:
GT_PROJECT_ID=your-project-id GT_API_KEY=gtx-api-your-production-key -
Run the translate command to translate your content:
npx gtx-cli translateYou can configure the behavior of the translate command with the
gt.config.jsonfile.See the CLI Tool reference guide for more information.
-
Update your build script to translate before building:
package.json { "scripts": { "build": "npx gtx-cli translate && <...YOUR_BUILD_COMMAND...>" } }
Next steps
<T>Component Guide - Deep dive into the<T>component and JSX translation- String Translation Guide - Using
useGT - Variable Components - Handle dynamic content with
<Var>,<Num>, etc.
How is this guide?