Skip to content

Commit 4c73c86

Browse files
committed
Add localization doc
1 parent e82a470 commit 4c73c86

File tree

5 files changed

+217
-0
lines changed

5 files changed

+217
-0
lines changed

docs/localization.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
id: localization
3+
title: Localization
4+
sidebar_label: Localization
5+
---
6+
7+
English is only one of many languages that people speak around the world (thanks a lot, [Tower of Babel](https://en.wikipedia.org/wiki/Tower_of_Babel)) and it's polite and sometimes even necessary to translate to your app into the languages that your users speak. Let's look at one way you can do this in React Navigation - it's not the only way but it'll do the trick. Similar to [themes](themes.html), we will use `screenProps`. You may want to also use React's context API as demonstrated in the [themes](themes.html) guide in order to make it easier to access the translate function from a variety of components.
8+
9+
## Setting up a localization library
10+
11+
We'll need to use some kind of library to store our translations and provide a function that gives us access to them, along with handling fallbacks when we don't have a particular language defined. Localization and internationalization (i18n) are often used interchangably, as in the example below where we get the current `locale` from `expo-localization` and use the `i18n-js` library for managing translations, for no particular reason other than it was available - use whatever you like.
12+
13+
```jsx
14+
import { Localization } from 'expo-localization'; // or whatever library you want
15+
import i18n from 'i18n-js';
16+
17+
const en = {
18+
foo: 'Foo',
19+
bar: 'Bar {{someValue}}',
20+
};
21+
22+
const fr = {
23+
foo: 'Fou',
24+
bar: 'Bár {{someValue}}',
25+
};
26+
27+
i18n.fallbacks = true;
28+
i18n.translations = { fr, en };
29+
30+
// This will log 'en' for me, as I'm an English speaker
31+
console.log(Localization.locale);
32+
```
33+
34+
## Wiring up your localization library to navigation
35+
36+
Next let's store our `locale` in the state of our root app component and then thread it through `screenProps` to make it available throughout React Navigation.
37+
38+
```jsx
39+
export default class App extends React.Component {
40+
state = {
41+
locale: Localization.locale,
42+
};
43+
44+
setLocale = locale => {
45+
this.setState({ locale });
46+
};
47+
48+
t = (scope, options) => {
49+
return i18n.t(scope, { locale: this.state.locale, ...options });
50+
};
51+
52+
render() {
53+
return (
54+
<AppContainer
55+
screenProps={{
56+
t: this.t,
57+
locale: this.state.locale,
58+
setLocale: this.setLocale,
59+
}}
60+
/>
61+
);
62+
}
63+
}
64+
```
65+
66+
Now in our screens we can use these `screenProps` as follows:
67+
68+
```jsx
69+
class Screen extends React.Component {
70+
static navigationOptions = ({ screenProps: { t } }) => ({
71+
title: t('foo'),
72+
});
73+
74+
render() {
75+
let { t, locale } = this.props.screenProps;
76+
77+
return (
78+
<View style={styles.container}>
79+
<Text style={styles.text}>
80+
Current locale: {locale}.{' '}
81+
{locale !== 'en' && locale !== 'fr'
82+
? 'Translations will fall back to "en" because none available'
83+
: null}
84+
</Text>
85+
<Text>{t('bar', { someValue: Date.now() })}</Text>
86+
{locale === 'en' ? (
87+
<Button
88+
title="Switch to French"
89+
onPress={() => this.props.screenProps.setLocale('fr')}
90+
/>
91+
) : (
92+
<Button
93+
title="Switch to English"
94+
onPress={() => this.props.screenProps.setLocale('en')}
95+
/>
96+
)}
97+
</View>
98+
);
99+
}
100+
}
101+
```
102+
103+
You can run this example in [this Snack](https://snack.expo.io/@react-navigation/localization-example). Again, you may want to go further than just passing this through `screenProps` if you want to make it easier to access the `t` function or the other `screenProps` from any React component (and not just screen components that are rendered by React Navigation). Refer to [themes](themes.html) and the [React documentation on context](https://reactjs.org/docs/context.html) for help with that.

website/i18n/en.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@
132132
"title": "Know when a screen is focused and blurred",
133133
"sidebar_label": "Know when a screen is focused and blurred"
134134
},
135+
"localization": {
136+
"title": "Localization",
137+
"sidebar_label": "Localization"
138+
},
135139
"material-bottom-tab-navigator": {
136140
"title": "createMaterialBottomTabNavigator",
137141
"sidebar_label": "createMaterialBottomTabNavigator"
@@ -745,6 +749,10 @@
745749
"title": "Limitations",
746750
"sidebar_label": "Limitations"
747751
},
752+
"version-3.x-localization": {
753+
"title": "Localization",
754+
"sidebar_label": "Localization"
755+
},
748756
"version-3.x-material-bottom-tab-navigator": {
749757
"title": "createMaterialBottomTabNavigator",
750758
"sidebar_label": "createMaterialBottomTabNavigator"

website/sidebars.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"state-persistence",
3535
"redux-integration",
3636
"MST-integration",
37+
"localization",
3738
"web-support",
3839
"function-after-focusing-screen"
3940
],
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
original_id: localization
3+
id: version-3.x-localization
4+
title: Localization
5+
sidebar_label: Localization
6+
---
7+
8+
English is only one of many languages that people speak around the world (thanks a lot, [Tower of Babel](https://en.wikipedia.org/wiki/Tower_of_Babel)) and it's polite and sometimes even necessary to translate to your app into the languages that your users speak. Let's look at one way you can do this in React Navigation - it's not the only way but it'll do the trick. Similar to [themes](themes.html), we will use `screenProps`. You may want to also use React's context API as demonstrated in the [themes](themes.html) guide in order to make it easier to access the translate function from a variety of components.
9+
10+
## Setting up a localization library
11+
12+
We'll need to use some kind of library to store our translations and provide a function that gives us access to them, along with handling fallbacks when we don't have a particular language defined. Localization and internationalization (i18n) are often used interchangably, as in the example below where we get the current `locale` from `expo-localization` and use the `i18n-js` library for managing translations, for no particular reason other than it was available - use whatever you like.
13+
14+
```jsx
15+
import { Localization } from 'expo-localization'; // or whatever library you want
16+
import i18n from 'i18n-js';
17+
18+
const en = {
19+
foo: 'Foo',
20+
bar: 'Bar {{someValue}}',
21+
};
22+
23+
const fr = {
24+
foo: 'Fou',
25+
bar: 'Bár {{someValue}}',
26+
};
27+
28+
i18n.fallbacks = true;
29+
i18n.translations = { fr, en };
30+
31+
// This will log 'en' for me, as I'm an English speaker
32+
console.log(Localization.locale);
33+
```
34+
35+
## Wiring up your localization library to navigation
36+
37+
Next let's store our `locale` in the state of our root app component and then thread it through `screenProps` to make it available throughout React Navigation.
38+
39+
```jsx
40+
export default class App extends React.Component {
41+
state = {
42+
locale: Localization.locale,
43+
};
44+
45+
setLocale = locale => {
46+
this.setState({ locale });
47+
};
48+
49+
t = (scope, options) => {
50+
return i18n.t(scope, { locale: this.state.locale, ...options });
51+
};
52+
53+
render() {
54+
return (
55+
<AppContainer
56+
screenProps={{
57+
t: this.t,
58+
locale: this.state.locale,
59+
setLocale: this.setLocale,
60+
}}
61+
/>
62+
);
63+
}
64+
}
65+
```
66+
67+
Now in our screens we can use these `screenProps` as follows:
68+
69+
```jsx
70+
class Screen extends React.Component {
71+
static navigationOptions = ({ screenProps: { t } }) => ({
72+
title: t('foo'),
73+
});
74+
75+
render() {
76+
let { t, locale } = this.props.screenProps;
77+
78+
return (
79+
<View style={styles.container}>
80+
<Text style={styles.text}>
81+
Current locale: {locale}.{' '}
82+
{locale !== 'en' && locale !== 'fr'
83+
? 'Translations will fall back to "en" because none available'
84+
: null}
85+
</Text>
86+
<Text>{t('bar', { someValue: Date.now() })}</Text>
87+
{locale === 'en' ? (
88+
<Button
89+
title="Switch to French"
90+
onPress={() => this.props.screenProps.setLocale('fr')}
91+
/>
92+
) : (
93+
<Button
94+
title="Switch to English"
95+
onPress={() => this.props.screenProps.setLocale('en')}
96+
/>
97+
)}
98+
</View>
99+
);
100+
}
101+
}
102+
```
103+
104+
You can run this example in [this Snack](https://snack.expo.io/@react-navigation/localization-example). Again, you may want to go further than just passing this through `screenProps` if you want to make it easier to access the `t` function or the other `screenProps` from any React component (and not just screen components that are rendered by React Navigation). Refer to [themes](themes.html) and the [React documentation on context](https://reactjs.org/docs/context.html) for help with that.

website/versioned_sidebars/version-3.x-sidebars.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"version-3.x-state-persistence",
3535
"version-3.x-redux-integration",
3636
"version-3.x-MST-integration",
37+
"version-3.x-localization",
3738
"version-3.x-web-support",
3839
"version-3.x-function-after-focusing-screen"
3940
],

0 commit comments

Comments
 (0)