├── example
├── react-native-expo
│ ├── .watchmanconfig
│ ├── app.json
│ ├── .babelrc
│ ├── .gitignore
│ ├── package.json
│ ├── App.js
│ ├── js
│ │ ├── pages
│ │ │ ├── Page2.js
│ │ │ └── Home.js
│ │ └── i18n.js
│ └── .flowconfig
├── react_withHOC
│ ├── .env
│ ├── src
│ │ ├── index.css
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── i18n.js
│ │ ├── App.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ ├── manifest.json
│ │ └── index.html
│ ├── .gitignore
│ └── package.json
├── react_fluent_withHOC
│ ├── .env
│ ├── src
│ │ ├── index.css
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── i18n.js
│ │ ├── App.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── manifest.json
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.ftl
│ │ │ └── de
│ │ │ │ └── translations.ftl
│ │ └── index.html
│ ├── .gitignore
│ └── package.json
├── react_icu_withHOC
│ ├── .env
│ ├── src
│ │ ├── index.css
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── i18n.js
│ │ ├── App.js
│ │ ├── logo.svg
│ │ └── ComponentUsingMacro.js
│ ├── public
│ │ ├── favicon.ico
│ │ ├── manifest.json
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ └── index.html
│ ├── .gitignore
│ └── package.json
├── razzle-ssr
│ ├── public
│ │ ├── robots.txt
│ │ └── favicon.ico
│ ├── .babelrc
│ ├── src
│ │ ├── App.css
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ ├── translations.json
│ │ │ │ └── translations.missing.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ ├── App.js
│ │ ├── index.js
│ │ ├── Home.css
│ │ ├── client.js
│ │ ├── i18n.js
│ │ ├── Home.js
│ │ └── server.js
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── nextjs-locize
│ ├── .babelrc
│ ├── video_sample.png
│ ├── locizeOptions.json
│ ├── components
│ │ ├── PureComponent.js
│ │ └── ExtendedComponent.js
│ ├── package.json
│ ├── pages
│ │ ├── page2.js
│ │ └── index.js
│ ├── server.js
│ ├── i18n.js
│ └── README.md
├── dat
│ ├── src
│ │ ├── index.css
│ │ ├── whichBackend.js
│ │ ├── App.test.js
│ │ ├── App.css
│ │ ├── index.js
│ │ ├── App.js
│ │ ├── i18n.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ ├── manifest.json
│ │ └── index.html
│ ├── README.md
│ ├── .gitignore
│ └── package.json
├── storybook
│ ├── src
│ │ ├── index.css
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── i18n.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── manifest.json
│ │ └── index.html
│ ├── .storybook
│ │ └── config.js
│ ├── stories
│ │ ├── SayWelcome.js
│ │ └── index.js
│ ├── .gitignore
│ ├── README.md
│ └── package.json
├── test-jest
│ ├── src
│ │ ├── index.css
│ │ ├── setupTests.js
│ │ ├── MyComponent.js
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── MyComponent.test.js
│ │ ├── i18n.js
│ │ ├── App.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ ├── manifest.json
│ │ └── index.html
│ ├── README.md
│ ├── .gitignore
│ ├── package.json
│ └── __mocks__
│ │ └── react-i18next.js
├── locize-example
│ ├── src
│ │ ├── index.css
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── App.js
│ │ ├── i18n.js
│ │ └── logo.svg
│ ├── video_sample.png
│ ├── public
│ │ ├── favicon.ico
│ │ ├── manifest.json
│ │ └── index.html
│ ├── .gitignore
│ ├── package.json
│ └── README.md
├── preact_renderProps
│ ├── src
│ │ ├── index.css
│ │ ├── setupTests.js
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── i18n.js
│ │ ├── App.js
│ │ ├── registerServiceWorker.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ ├── manifest.json
│ │ └── index.html
│ ├── README.md
│ ├── .gitignore
│ └── package.json
├── preact_withHOC
│ ├── src
│ │ ├── index.css
│ │ ├── setupTests.js
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── i18n.js
│ │ ├── App.js
│ │ ├── registerServiceWorker.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ ├── manifest.json
│ │ └── index.html
│ ├── README.md
│ ├── .gitignore
│ └── package.json
├── react_renderProps
│ ├── src
│ │ ├── index.css
│ │ ├── App.test.js
│ │ ├── index.js
│ │ ├── App.css
│ │ ├── i18n.js
│ │ ├── App.js
│ │ └── logo.svg
│ ├── public
│ │ ├── favicon.ico
│ │ ├── locales
│ │ │ ├── en
│ │ │ │ └── translations.json
│ │ │ └── de
│ │ │ │ └── translations.json
│ │ ├── manifest.json
│ │ └── index.html
│ ├── .gitignore
│ └── package.json
├── nextjs_withAppJS
│ ├── locales
│ │ ├── en
│ │ │ ├── page2.json
│ │ │ ├── home.json
│ │ │ └── common.json
│ │ └── de
│ │ │ ├── page2.json
│ │ │ ├── home.json
│ │ │ └── common.json
│ ├── components
│ │ ├── PureComponent.js
│ │ ├── ExtendedComponent.js
│ │ └── ComponentWithTrans.js
│ ├── pages
│ │ ├── page3.js
│ │ ├── _app.js
│ │ ├── page2.js
│ │ └── index.js
│ ├── package.json
│ ├── lib
│ │ └── withI18next.js
│ ├── server.js
│ ├── i18n.js
│ └── README.md
└── nextjs
│ └── README.md
├── .eslintignore
├── test
├── setup.js
├── trans.spec.js
├── backendMock.js
├── interpolate.spec.js
├── I18n.spec.js
├── i18n.render.spec.js
├── translate.render.spec.js
├── loadNamespaces.spec.js
├── interpolate.render.spec.js
├── translate.render.nsMode.spec.js
├── i18n.js
├── translate.render.wait.spec.js
├── icu.macro.spec.js
└── i18nextProvider.spec.js
├── .npmignore
├── .editorconfig
├── .travis.yml
├── .babelrc
├── .gitignore
├── src
├── index.js
├── context.js
├── loadNamespaces.js
├── I18nextProvider.js
└── shallowEqual.js
├── bower.json
├── .codeclimate.yml
├── rollup.config.js
├── LICENSE
└── .eslintrc
/example/react-native-expo/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/example/react_withHOC/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
--------------------------------------------------------------------------------
/example/react_icu_withHOC/.env:
--------------------------------------------------------------------------------
1 | SKIP_PREFLIGHT_CHECK=true
--------------------------------------------------------------------------------
/example/razzle-ssr/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 |
3 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/dist/*
2 | **/node_modules/*
3 | **/*.min.*
4 |
--------------------------------------------------------------------------------
/example/nextjs-locize/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["next/babel"],
3 | }
4 |
--------------------------------------------------------------------------------
/example/razzle-ssr/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "react", "es2015", "stage-0" ]
3 | }
4 |
--------------------------------------------------------------------------------
/example/react-native-expo/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "sdkVersion": "27.0.0"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/example/dat/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/App.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
--------------------------------------------------------------------------------
/example/react_withHOC/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/storybook/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/test-jest/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/dat/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/dat/public/favicon.ico
--------------------------------------------------------------------------------
/example/locize-example/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/react_renderProps/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/setupTests.js:
--------------------------------------------------------------------------------
1 | //https://github.com/developit/preact/issues/444
2 | global.SVGElement = global.Element;
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/test/setup.js:
--------------------------------------------------------------------------------
1 | import 'raf/polyfill';
2 |
3 | import configure from 'enzyme-adapter-react-helper';
4 |
5 | configure();
6 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/setupTests.js:
--------------------------------------------------------------------------------
1 | //https://github.com/developit/preact/issues/444
2 | global.SVGElement = global.Element;
--------------------------------------------------------------------------------
/example/nextjs-locize/video_sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/nextjs-locize/video_sample.png
--------------------------------------------------------------------------------
/example/razzle-ssr/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/razzle-ssr/public/favicon.ico
--------------------------------------------------------------------------------
/example/storybook/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/storybook/public/favicon.ico
--------------------------------------------------------------------------------
/example/test-jest/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/test-jest/public/favicon.ico
--------------------------------------------------------------------------------
/example/locize-example/video_sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/locize-example/video_sample.png
--------------------------------------------------------------------------------
/example/react_withHOC/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/react_withHOC/public/favicon.ico
--------------------------------------------------------------------------------
/example/locize-example/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/locize-example/public/favicon.ico
--------------------------------------------------------------------------------
/example/preact_withHOC/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/preact_withHOC/public/favicon.ico
--------------------------------------------------------------------------------
/example/preact_renderProps/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/preact_renderProps/public/favicon.ico
--------------------------------------------------------------------------------
/example/react_icu_withHOC/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/react_icu_withHOC/public/favicon.ico
--------------------------------------------------------------------------------
/example/react_renderProps/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/react_renderProps/public/favicon.ico
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-i18next/master/example/react_fluent_withHOC/public/favicon.ico
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/locales/en/page2.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcomePage2": "this is page 2",
3 | "link": {
4 | "gotoPage1": "Back to page 1"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/locales/de/page2.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcomePage2": "Dies ist die 2te Seite",
3 | "link": {
4 | "gotoPage1": "Zur Seite 1"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/example/test-jest/src/setupTests.js:
--------------------------------------------------------------------------------
1 | import Enzyme from 'enzyme';
2 | import Adapter from 'enzyme-adapter-react-16';
3 |
4 | Enzyme.configure({ adapter: new Adapter() })
5 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/components/PureComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default function PureComponent ({ t }) {
4 | return
{t('common:pureComponent')}
5 | }
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | test/
2 | coverage/
3 | example/
4 | bin/
5 | .babelrc
6 | .editorconfig
7 | .eslintignore
8 | .eslintrc
9 | .gitignore
10 | bower.json
11 | gulpfile.js
12 | karma.conf.js
13 |
--------------------------------------------------------------------------------
/example/react-native-expo/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["babel-preset-expo"],
3 | "env": {
4 | "development": {
5 | "plugins": ["transform-react-jsx-source"]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/example/storybook/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import { configure } from '@storybook/react';
2 |
3 | function loadStories() {
4 | require('../stories');
5 | }
6 |
7 | configure(loadStories, module);
8 |
--------------------------------------------------------------------------------
/example/nextjs-locize/locizeOptions.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectId": "4be4b1b5-a728-4564-8cfd-6853804b95e7",
3 | "apiKey": "b393a857-278a-4639-9941-f7b26b00c36e",
4 | "referenceLng": "en",
5 | "version": "latest"
6 | }
7 |
--------------------------------------------------------------------------------
/example/dat/src/whichBackend.js:
--------------------------------------------------------------------------------
1 | module.exports = () => {
2 | const params = (new URL(document.location)).searchParams;
3 | const backend = (params.get('backend') || 'memory').toLowerCase();
4 | return backend;
5 | }
6 |
--------------------------------------------------------------------------------
/example/storybook/stories/SayWelcome.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 |
4 | const SayWelcome = ({ t }) => (
5 |
6 | {t('Welcome to React')}
7 |
8 | );
9 |
10 | export default SayWelcome;
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 | root = true
3 |
4 | [*.{js,jsx,json}]
5 | end_of_line = lf
6 | insert_final_newline = true
7 | charset = utf-8
8 | indent_style = space
9 | indent_size = 2
10 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { h, render } from 'preact';
2 | import App from './App';
3 |
4 | it('renders without crashing', () => {
5 | const div = document.createElement('div');
6 | render( , div);
7 | });
8 |
--------------------------------------------------------------------------------
/example/razzle-ssr/.gitignore:
--------------------------------------------------------------------------------
1 | logs
2 | *.log
3 | npm-debug.log*
4 | .DS_Store
5 |
6 | coverage
7 | node_modules
8 | build
9 | .env.local
10 | .env.development.local
11 | .env.test.local
12 | .env.production.local
13 | yarn.lock
14 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "message": {
3 | "welcome": "Welcome to Razzle with i18n"
4 | },
5 | "guideline": "To get started, edit <1>src/App.js1> or <3>src/Home.js3> and save to reload."
6 | }
7 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/locales/en/translations.missing.json:
--------------------------------------------------------------------------------
1 | {
2 | "message": {
3 | "welcome": "Welcome to Razzle"
4 | },
5 | "guideline": "To get started, edit <1>src/App.js1> or <3>src/Home.js3> and save to reload."
6 | }
7 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { h, render } from 'preact';
2 | import App from './App';
3 |
4 | it('renders without crashing', () => {
5 | const div = document.createElement('div');
6 | render( , div);
7 | });
8 |
--------------------------------------------------------------------------------
/example/dat/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render( , div);
8 | });
9 |
--------------------------------------------------------------------------------
/example/storybook/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render( , div);
8 | });
9 |
--------------------------------------------------------------------------------
/example/locize-example/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render( , div);
8 | });
9 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "message": {
3 | "welcome": "Willkommen zu Razzle mit i18n"
4 | },
5 | "guideline": "Um zu beginnen, ändere <1>src/App.js1> oder <3>src/Home.js3> und speichere deine Änderungen um neu zu laden."
6 | }
7 |
--------------------------------------------------------------------------------
/example/preact_withHOC/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create Preact App](https://github.com/just-boris/create-preact-app).
2 |
3 |
4 | ## start
5 |
6 | ```bash
7 | # npm start
8 | ```
9 |
10 | open `http://localhost:3000` to open your application.
11 |
--------------------------------------------------------------------------------
/example/react_renderProps/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render( , div);
8 | });
9 |
--------------------------------------------------------------------------------
/example/preact_renderProps/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create Preact App](https://github.com/just-boris/create-preact-app).
2 |
3 |
4 | ## start
5 |
6 | ```bash
7 | # npm start
8 | ```
9 |
10 | open `http://localhost:3000` to open your application.
11 |
--------------------------------------------------------------------------------
/example/test-jest/src/MyComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { translate } from 'react-i18next';
3 |
4 | export const CustomComponent = ({ t }) => {
5 | return {t('description.part2')}
6 | };
7 |
8 | export default translate('translations')(CustomComponent);
9 |
--------------------------------------------------------------------------------
/example/nextjs-locize/components/PureComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | // pure component just getting t function by props
4 | export default function PureComponent({ t }) {
5 | return (
6 |
7 | {t('common:pureComponent')}
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/example/dat/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
2 |
3 | ## using with Beaker Browser
4 | [hashbase](https://hashbase.io/locize/react-i18next)
5 |
6 | ## start locally
7 |
8 | ```bash
9 | # npm start
10 | ```
11 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/locales/de/home.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcome": "Willkommen zu next.js",
3 | "sample_test": "test words for de",
4 | "sample_button": "fire in the wind for de",
5 | "link": {
6 | "gotoPage2": "Zur Seite 2",
7 | "gotoPage3": "Zur Seite 3 (no hoc)"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/locales/en/home.json:
--------------------------------------------------------------------------------
1 | {
2 | "welcome": "welcome to next.js",
3 | "sample_test": "test words for en",
4 | "sample_button": "fire in the wind for en",
5 | "link": {
6 | "gotoPage2": "Go to page 2",
7 | "gotoPage3": "Go to page 3 (no hoc)"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/index.js:
--------------------------------------------------------------------------------
1 | import { h, render } from 'preact';
2 | import App from './App';
3 | import registerServiceWorker from './registerServiceWorker';
4 | import './index.css';
5 | import './i18n';
6 |
7 | render( , document.getElementById('root'));
8 | registerServiceWorker();
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 | env:
5 | - REACT=0.14
6 | - REACT=15
7 | - REACT=16
8 | script:
9 | - npm test
10 | after_success:
11 | - npm run test:coverage
12 | - cat ./coverage/lcov.info | node_modules/.bin/coveralls --verbose
13 | - rm -rf ./coverage
14 |
--------------------------------------------------------------------------------
/example/test-jest/public/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Welcome to react using react-i18next",
3 | "description": {
4 | "part1": "To get started, edit <1>src/App.js1> and save to reload.",
5 | "part2": "Switch language between english and german using buttons above."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | import './i18n';
6 |
7 | it('renders without crashing', () => {
8 | const div = document.createElement('div');
9 | ReactDOM.render( , div);
10 | });
11 |
--------------------------------------------------------------------------------
/example/react_withHOC/public/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Welcome to react using react-i18next",
3 | "description": {
4 | "part1": "To get started, edit <1>src/App.js1> and save to reload.",
5 | "part2": "Switch language between english and german using buttons above."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/react_withHOC/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | import './i18n';
6 |
7 | it('renders without crashing', () => {
8 | const div = document.createElement('div');
9 | ReactDOM.render( , div);
10 | });
11 |
--------------------------------------------------------------------------------
/example/preact_renderProps/public/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Welcome to preact using react-i18next",
3 | "description": {
4 | "part1": "To get started, edit <1>src/App.js1> and save to reload.",
5 | "part2": "Switch language between english and german using buttons above."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/preact_withHOC/public/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Welcome to preact using react-i18next",
3 | "description": {
4 | "part1": "To get started, edit <1>src/App.js1> and save to reload.",
5 | "part2": "Switch language between english and german using buttons above."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | import './i18n';
6 |
7 | it('renders without crashing', () => {
8 | const div = document.createElement('div');
9 | ReactDOM.render( , div);
10 | });
11 |
--------------------------------------------------------------------------------
/example/react_renderProps/public/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Welcome to react using react-i18next",
3 | "description": {
4 | "part1": "To get started, edit <1>src/App.js1> and save to reload.",
5 | "part2": "Switch language between english and german using buttons above."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/components/ExtendedComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { translate } from 'react-i18next'
3 |
4 | function MyComponent ({ t }) {
5 | return {t('extendedComponent')}
6 | }
7 |
8 | const Extended = translate('common')(MyComponent)
9 |
10 | export default Extended
11 |
--------------------------------------------------------------------------------
/example/test-jest/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 |
6 | it('renders without crashing', () => {
7 | const div = document.createElement('div');
8 | ReactDOM.render( , div);
9 | ReactDOM.unmountComponentAtNode(div);
10 | });
11 |
--------------------------------------------------------------------------------
/example/test-jest/README.md:
--------------------------------------------------------------------------------
1 | ### Intro
2 |
3 | `./__mocks__` contains the react-i18next mock (mocks translate and Trans; mock other components as needed!!!)
4 |
5 | `./src/setupTests.js` sets adapter for using enzyme
6 |
7 | `./src/App.test.js` basic test from create-react-app
8 | `./src/MyComponent.test.js` test using enzyme
9 |
--------------------------------------------------------------------------------
/example/test-jest/public/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Willkommen zu react und react-i18next",
3 | "description": {
4 | "part1": "Um loszulegen, ändere <1>src/App(DE).js1> speicheren und neuladen.",
5 | "part2": "Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/preact_withHOC/public/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Willkommen zu preact und react-i18next",
3 | "description": {
4 | "part1": "Um loszulegen, ändere <1>src/App(DE).js1> speicheren und neuladen.",
5 | "part2": "Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "development": {
4 | "presets": [ "react", "es2015", "stage-0" ]
5 | },
6 | "rollup": {
7 | "presets": [ "react", "es2015-rollup", "stage-0" ]
8 | },
9 | "jsnext": {
10 | "presets": [ "react", ["es2015", { "modules": false }], "stage-0" ]
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/dat/public/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "To get started, edit <1>src/App.js1> and save to reload.": "To get started, edit <1>src/App.js1> and save to reload.",
3 | "Welcome to React": "Welcome to React and react-i18next",
4 | "advice": "Try to set the query parameter \"backend\" to memory, xhr or locize i.e. {{url}}"
5 | }
6 |
--------------------------------------------------------------------------------
/example/preact_renderProps/public/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Willkommen zu preact und react-i18next",
3 | "description": {
4 | "part1": "Um loszulegen, ändere <1>src/App(DE).js1> speicheren und neuladen.",
5 | "part2": "Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/react_renderProps/public/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Willkommen zu react und react-i18next",
3 | "description": {
4 | "part1": "Um loszulegen, ändere <1>src/App(DE).js1> speicheren und neuladen.",
5 | "part2": "Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter."
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/test-jest/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | import './i18n';
8 |
9 | ReactDOM.render( , document.getElementById('root'));
10 | registerServiceWorker();
11 |
--------------------------------------------------------------------------------
/example/locize-example/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 |
4 | import './index.css';
5 | import App from './App';
6 | import './i18n';
7 | import registerServiceWorker from './registerServiceWorker';
8 |
9 | ReactDOM.render( , document.getElementById('root'));
10 | registerServiceWorker();
11 |
--------------------------------------------------------------------------------
/example/react_withHOC/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | import './i18n';
8 |
9 | ReactDOM.render( , document.getElementById('root'));
10 | registerServiceWorker();
11 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | import './i18n';
8 |
9 | ReactDOM.render( , document.getElementById('root'));
10 | registerServiceWorker();
11 |
--------------------------------------------------------------------------------
/example/react_renderProps/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | import './i18n';
8 |
9 | ReactDOM.render( , document.getElementById('root'));
10 | registerServiceWorker();
11 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/pages/page3.js:
--------------------------------------------------------------------------------
1 | // a page not using i18next - no hoc - not t function
2 | import React from 'react';
3 | import Link from 'next/link'
4 |
5 | export default () => {
6 | return (
7 |
8 |
Hello Page 3
9 |
10 |
back
11 |
12 |
13 | )
14 | };
15 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/index.js:
--------------------------------------------------------------------------------
1 | import { h, render } from 'preact';
2 | import { I18nextProvider } from 'react-i18next';
3 | import App from './App';
4 | import registerServiceWorker from './registerServiceWorker';
5 | import './index.css';
6 | import './i18n';
7 |
8 | render( , document.getElementById('root'));
9 | registerServiceWorker();
10 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import registerServiceWorker from './registerServiceWorker';
6 |
7 | import './i18n';
8 |
9 | ReactDOM.render( , document.getElementById('root'));
10 | registerServiceWorker();
11 |
--------------------------------------------------------------------------------
/example/dat/public/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "To get started, edit <1>src/App.js1> and save to reload.": "Starte in dem du, <1>src/App.js1> editierst und speicherst.",
3 | "Welcome to React": "Willkommen bei React und react-i18next",
4 | "advice": "Versuche den query Parameter \"backend\" auf memory, xhr oder locize zu setzen zBsp. {{url}}"
5 | }
6 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Route from 'react-router-dom/Route';
3 | import Switch from 'react-router-dom/Switch';
4 | import Home from './Home';
5 | import './App.css';
6 |
7 | const App = () => (
8 |
9 |
10 |
11 | );
12 |
13 | export default App;
14 |
--------------------------------------------------------------------------------
/example/react-native-expo/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # expo
4 | .expo/
5 |
6 | # dependencies
7 | /node_modules
8 |
9 | # misc
10 | .env.local
11 | .env.development.local
12 | .env.test.local
13 | .env.production.local
14 |
15 | npm-debug.log*
16 | yarn-debug.log*
17 | yarn-error.log*
18 |
--------------------------------------------------------------------------------
/example/react_withHOC/public/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Willkommen zu react und react-i18next",
3 | "description": {
4 | "part1":
5 | "Um loszulegen, ändere <1>src/App(DE).js1> speicheren und neuladen.",
6 | "part2":
7 | "Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter."
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/components/ComponentWithTrans.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Trans } from 'react-i18next'
3 |
4 | export default function ComponentWithTrans () {
5 | return (
6 |
7 |
8 | Alternatively, you can use Trans component.
9 |
10 |
11 | )
12 | }
13 |
--------------------------------------------------------------------------------
/example/dat/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/nextjs-locize/components/ExtendedComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { translate } from 'react-i18next';
3 | import i18n from '../i18n';
4 |
5 | function MyComponent({ t }) {
6 | return (
7 |
8 | {t('extendedComponent')}
9 |
10 | );
11 | }
12 |
13 | const Extended = translate('common')(MyComponent);
14 |
15 | export default Extended;
16 |
--------------------------------------------------------------------------------
/example/dat/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/storybook/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/locize-example/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/preact_withHOC/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/react_withHOC/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/preact_renderProps/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/react_renderProps/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/react_withHOC/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/storybook/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/test-jest/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/locize-example/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/locales/de/common.json:
--------------------------------------------------------------------------------
1 | {
2 | "integrates_react-i18next": "Dieses Beispiel integriert react-i18next für einfache Übersetzung.",
3 | "pureComponent": "Entweder t Funktion an Komponente via props weiterreichen.",
4 | "extendedComponent": "Oder die Komponente erneut mit dem translate hoc erweiteren.",
5 | "transComponent": "Sonst können Sie auch die Komponente <1>Trans1> verwenden."
6 | }
7 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/locales/en/common.json:
--------------------------------------------------------------------------------
1 | {
2 | "integrates_react-i18next": "This example integrates react-i18next for simple internationalization.",
3 | "pureComponent": "You can either pass t function to child components.",
4 | "extendedComponent": "Or wrap your component using the translate hoc provided by react-i18next.",
5 | "transComponent": "Alternatively, you can use <1>Trans1> component."
6 | }
7 |
--------------------------------------------------------------------------------
/example/preact_renderProps/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/preact_withHOC/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/react_renderProps/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore specific files
2 | .settings.xml
3 | .monitor
4 | .DS_Store
5 | *.orig
6 | npm-debug.log
7 | npm-debug.log.*
8 | *.dat
9 |
10 | # Ignore various temporary files
11 | *~
12 | *.swp
13 | .idea/
14 |
15 |
16 | # Ignore various Node.js related directories and files
17 | node_modules
18 | node_modules/**/*
19 | coverage/**/*
20 | example/build/**/*
21 | dist/**/*
22 | .next
23 | package-lock.json
24 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
--------------------------------------------------------------------------------
/example/test-jest/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { default as translate } from './translate';
2 | export { default as I18n } from './I18n';
3 | export { default as Interpolate } from './Interpolate';
4 | export { default as Trans } from './Trans';
5 | export { default as I18nextProvider } from './I18nextProvider';
6 | export { default as loadNamespaces } from './loadNamespaces';
7 | export { reactI18nextModule, setDefaults, getDefaults, setI18n, getI18n } from './context';
8 |
--------------------------------------------------------------------------------
/example/storybook/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { I18nextProvider } from 'react-i18next';
4 |
5 | import './index.css';
6 | import App from './App';
7 | import i18n from './i18n';
8 | import registerServiceWorker from './registerServiceWorker';
9 |
10 | ReactDOM.render( , document.getElementById('root'));
11 | registerServiceWorker();
12 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/public/locales/en/translations.ftl:
--------------------------------------------------------------------------------
1 | title = Welcome to react using react-i18next with fluent
2 |
3 | description_1 = To get started, edit <1>src/App.js1> and save to reload.
4 | description_2 = Switch language between english and german using buttons above.
5 |
6 | emails =
7 | { $unreadEmails ->
8 | [one] You have <1>one1> unread email.
9 | *[other] You have <1>{ $unreadEmails }1> unread emails.
10 | }
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-i18next",
3 | "main": "./react-i18next.min.js",
4 | "dependencies": {},
5 | "ignore": [
6 | "test/",
7 | "dist/",
8 | "src/",
9 | "bin/",
10 | "coverage/",
11 | "example/",
12 | ".babelrc",
13 | ".gitignore",
14 | ".editorconfig",
15 | ".eslintignore",
16 | ".eslintrc",
17 | ".npmignore",
18 | "gulpfile.js",
19 | "package.json",
20 | "karma.conf.js"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/example/dat/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/test/trans.spec.js:
--------------------------------------------------------------------------------
1 | jest.unmock('../src/Trans');
2 | import React from 'react';
3 | import PropTypes from 'prop-types';
4 | import Trans from '../src/Trans';
5 |
6 | describe('trans', () => {
7 | it('should have some stuff', () => {
8 | expect(Trans.contextTypes.i18n)
9 | .toBe(PropTypes.object);
10 | expect(Trans.propTypes.i18n)
11 | .toBe(PropTypes.object);
12 | expect(Trans.propTypes.t)
13 | .toBe(PropTypes.func);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/example/storybook/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/locize-example/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/react_withHOC/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/react_renderProps/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/public/locales/de/translations.ftl:
--------------------------------------------------------------------------------
1 | title = Willkommen zu react und react-i18next mit fluent
2 |
3 | description_1 = Um loszulegen, ändere <1>src/App(DE).js1> speicheren und neuladen.
4 | description_2 = Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter.
5 |
6 | emails =
7 | { $unreadEmails ->
8 | [one] Du hast <1>eine1> ungelesene Email.
9 | *[other] Du hast <1>{ $unreadEmails }1> ungelesene Emails.
10 | }
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | engines:
2 | duplication:
3 | enabled: true
4 | config:
5 | languages:
6 | - ruby
7 | - javascript:
8 | mass_threshold: 58
9 | - python
10 | - php
11 | eslint:
12 | enabled: true
13 | fixme:
14 | enabled: true
15 | ratings:
16 | paths:
17 | - "src/**/*"
18 | exclude_paths:
19 | - test/
20 | - coverage/
21 | - dist/
22 | - example/
23 | - "react-i18next.js"
24 | - "react-i18next.min.js"
25 | - "rollup.config.js"
26 | - "src/shallowEqual.js"
27 |
--------------------------------------------------------------------------------
/example/test-jest/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-title {
18 | font-size: 1.5em;
19 | }
20 |
21 | .App-intro {
22 | font-size: large;
23 | }
24 |
25 | @keyframes App-logo-spin {
26 | from { transform: rotate(0deg); }
27 | to { transform: rotate(360deg); }
28 | }
29 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/public/locales/en/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Welcome to react using react-i18next",
3 | "description": {
4 | "part1": "To get started, edit <1>src/App.js1> and save to reload.",
5 | "part2": "Switch language between english and german using buttons above."
6 | },
7 | "icu":
8 | "{numPersons, plural, =0 {no persons} =1 {one person} other {# persons}}",
9 | "icu_and_trans":
10 | "We invited <0>{numPersons, plural, =0 {no persons} =1 {one person} other {# persons}}0>."
11 | }
12 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/index.js:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import app from './server';
3 |
4 | if (module.hot) {
5 | module.hot.accept('./server', function() {
6 | console.log('🔁 HMR Reloading `./server`...');
7 | });
8 | console.info('✅ Server-side HMR Enabled!');
9 | }
10 |
11 | const port = process.env.PORT || 3000;
12 |
13 | export default express()
14 | .use((req, res) => app.handle(req, res))
15 | .listen(port, function(err) {
16 | if (err) {
17 | console.error(err);
18 | return;
19 | }
20 | console.log(`> Started on port ${port}`);
21 | });
22 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/public/locales/de/translations.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Willkommen zu react und react-i18next",
3 | "description": {
4 | "part1":
5 | "Um loszulegen, ändere <1>src/App(DE).js1> speicheren und neuladen.",
6 | "part2":
7 | "Ändere die Sprachen zwischen deutsch und englisch mit Hilfe der beiden Schalter."
8 | },
9 | "icu":
10 | "{numPersons, plural, =0 {keine Person} =1 {eine Person} other {# Personen}}",
11 | "icu_and_trans":
12 | "Wir haben <0>{numPersons, plural, =0 {keine Person} =1 {eine Person} other {# Personen}}0> eingeladen."
13 | }
14 |
--------------------------------------------------------------------------------
/example/react_renderProps/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react_renderprops",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^16.0.0",
7 | "react-dom": "^16.0.0",
8 | "react-scripts": "1.0.14",
9 | "i18next": "9.0.1",
10 | "i18next-browser-languagedetector": "2.0.0",
11 | "i18next-xhr-backend": "1.4.3",
12 | "react-i18next": "6.0.6"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test --env=jsdom",
18 | "eject": "react-scripts eject"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/example/storybook/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
2 |
3 |
4 | ## start app
5 |
6 | ```bash
7 | # npm start
8 | ```
9 |
10 | ## start storybook
11 |
12 | ```bash
13 | # npm run storybook
14 | ```
15 |
16 | ## information
17 |
18 | In the sample we show both a component being decorated by translate hoc using a [storybook decorator](https://storybook.js.org/basics/writing-stories/#using-decorators) to wrap the `I18nextProvider` around the decorated component and a pure component just expecting a t function which we pass in with a mock function.
19 |
--------------------------------------------------------------------------------
/test/backendMock.js:
--------------------------------------------------------------------------------
1 | class Backend {
2 | constructor(services, options = {}) {
3 | this.init(services, options);
4 | this.type = 'backend'
5 | this.queue = [];
6 | }
7 |
8 | init(services, options) {
9 | this.services = services;
10 | this.options = options;
11 | }
12 |
13 | read(language, namespace, callback) {
14 | this.queue.push(callback);
15 | }
16 |
17 | flush() {
18 | this.queue.forEach(cb => {
19 | cb(null, {
20 | key1: 'test',
21 | interpolateKey: 'add {{insert}} {{up, uppercase}}'
22 | });
23 | })
24 | }
25 | }
26 |
27 |
28 | export default Backend;
29 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/Home.css:
--------------------------------------------------------------------------------
1 | .Home {
2 | text-align: center;
3 | }
4 |
5 | .Home-logo {
6 | animation: Home-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .Home-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .Home-intro {
18 | margin-top: 30px;
19 | font-size: large;
20 | }
21 |
22 | .Home-resources {
23 | list-style: none;
24 | }
25 |
26 | .Home-resources > li {
27 | display: inline-block;
28 | padding: 1rem;
29 | }
30 |
31 | @keyframes Home-logo-spin {
32 | from { transform: rotate(0deg); }
33 | to { transform: rotate(360deg); }
34 | }
35 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/client.js:
--------------------------------------------------------------------------------
1 | import App from './App';
2 | import BrowserRouter from 'react-router-dom/BrowserRouter';
3 | import React from 'react';
4 | import { render } from 'react-dom';
5 |
6 | import { I18nextProvider } from 'react-i18next';
7 | import i18n from './i18n';
8 |
9 | render(
10 |
15 |
16 |
17 |
18 | ,
19 | document.getElementById('root')
20 | );
21 |
22 | if (module.hot) {
23 | module.hot.accept();
24 | }
25 |
--------------------------------------------------------------------------------
/example/preact_withHOC/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "preact-i18next-example-with-hoc",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@just-boris/preact-scripts": "1.0.7",
7 | "i18next": "8.4.3",
8 | "i18next-browser-languagedetector": "2.0.0",
9 | "i18next-xhr-backend": "1.4.2",
10 | "preact": "8.2.1",
11 | "preact-compat": "3.16.0",
12 | "react-i18next": "7.3.6"
13 | },
14 | "devDependencies": {},
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test --env=jsdom",
19 | "eject": "react-scripts eject"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/example/dat/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dat-react-i18next-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "i18next": "8.4.2",
7 | "i18next-browser-languagedetector": "2.0.0",
8 | "i18next-locize-backend": "1.0.0",
9 | "i18next-xhr-backend": "1.4.2",
10 | "react": "15.6.1",
11 | "react-dom": "15.6.1",
12 | "react-i18next": "4.6.1",
13 | "react-scripts": "1.0.10"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test --env=jsdom",
19 | "eject": "react-scripts eject"
20 | },
21 | "devDependencies": {}
22 | }
23 |
--------------------------------------------------------------------------------
/example/preact_renderProps/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "preact-i18next-example-with-renderprops",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@just-boris/preact-scripts": "1.0.7",
7 | "i18next": "8.4.3",
8 | "i18next-browser-languagedetector": "2.0.0",
9 | "i18next-xhr-backend": "1.4.2",
10 | "preact": "8.2.1",
11 | "preact-compat": "3.16.0",
12 | "react-i18next": "7.3.6"
13 | },
14 | "devDependencies": {},
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test --env=jsdom",
19 | "eject": "react-scripts eject"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/example/locize-example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "locize-react-i18next-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "i18next": "11.9.0",
7 | "i18next-browser-languagedetector": "2.2.3",
8 | "i18next-locize-backend": "1.6.0",
9 | "locize-editor": "1.6.0",
10 | "react": "16.2.0",
11 | "react-dom": "16.2.0",
12 | "react-i18next": "7.1.1",
13 | "react-scripts": "1.0.17"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test --env=jsdom",
19 | "eject": "react-scripts eject"
20 | },
21 | "devDependencies": {}
22 | }
23 |
--------------------------------------------------------------------------------
/example/test-jest/src/MyComponent.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { mount } from 'enzyme';
3 | import MyComponent, { CustomComponent } from './MyComponent';
4 |
5 |
6 | it('test render of named export', () => {
7 | const mounted = mount( 'translate hardcoded'} />);
8 |
9 | // console.log(mounted.debug());
10 | expect(mounted.contains(translate hardcoded
)).toBe(true);
11 | });
12 |
13 | it('test render of component inside hoc (default export)', () => {
14 | const mounted = mount( );
15 |
16 | // console.log(mounted.debug());
17 | expect(mounted.contains(description.part2
)).toBe(true);
18 | });
19 |
--------------------------------------------------------------------------------
/example/test-jest/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "test-jest",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "enzyme": "3.3.0",
7 | "enzyme-adapter-react-16": "^1.1.1",
8 | "i18next": "11.3.2",
9 | "i18next-browser-languagedetector": "2.2.0",
10 | "i18next-xhr-backend": "1.5.1",
11 | "raf": "3.4.0",
12 | "react": "16.3.2",
13 | "react-dom": "16.3.2",
14 | "react-i18next": "7.6.1",
15 | "react-scripts": "1.1.4"
16 | },
17 | "scripts": {
18 | "start": "react-scripts start",
19 | "build": "react-scripts build",
20 | "test": "react-scripts test --env=jsdom",
21 | "eject": "react-scripts eject"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/nextjs/README.md:
--------------------------------------------------------------------------------
1 | # Getting started
2 |
3 | You find the example for next.js and react-i18next here:
4 |
5 | [https://github.com/zeit/next.js/tree/canary/examples/with-react-i18next](https://github.com/zeit/next.js/tree/canary/examples/with-react-i18next)
6 |
7 | *Using one place for the example makes it easier so we do not have to sync them on every change.*
8 |
9 | Beside that there is also a sample to show the usage with **locize** here:
10 |
11 | [https://github.com/i18next/react-i18next/tree/master/example/nextjs-locize](https://github.com/i18next/react-i18next/tree/master/example/nextjs-locize)
12 |
13 | If you like to cover the full localization process beside instrumenting your code for i18n.
14 |
--------------------------------------------------------------------------------
/example/react_withHOC/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import Backend from 'i18next-xhr-backend';
3 | import LanguageDetector from 'i18next-browser-languagedetector';
4 | import { reactI18nextModule } from 'react-i18next';
5 |
6 | i18n
7 | .use(Backend)
8 | .use(LanguageDetector)
9 | .use(reactI18nextModule)
10 | .init({
11 | fallbackLng: 'en',
12 |
13 | // have a common namespace used around the full app
14 | ns: ['translations'],
15 | defaultNS: 'translations',
16 |
17 | debug: true,
18 |
19 | interpolation: {
20 | escapeValue: false, // not needed for react!!
21 | },
22 |
23 | react: {
24 | wait: true
25 | }
26 | });
27 |
28 |
29 | export default i18n;
30 |
--------------------------------------------------------------------------------
/example/test-jest/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import Backend from 'i18next-xhr-backend';
3 | import LanguageDetector from 'i18next-browser-languagedetector';
4 | import { reactI18nextModule } from 'react-i18next';
5 |
6 | i18n
7 | .use(Backend)
8 | .use(LanguageDetector)
9 | .use(reactI18nextModule)
10 | .init({
11 | fallbackLng: 'en',
12 |
13 | // have a common namespace used around the full app
14 | ns: ['translations'],
15 | defaultNS: 'translations',
16 |
17 | debug: true,
18 |
19 | interpolation: {
20 | escapeValue: false, // not needed for react!!
21 | },
22 |
23 | react: {
24 | wait: true
25 | }
26 | });
27 |
28 |
29 | export default i18n;
30 |
--------------------------------------------------------------------------------
/example/react_renderProps/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import Backend from 'i18next-xhr-backend';
3 | import LanguageDetector from 'i18next-browser-languagedetector';
4 | import { reactI18nextModule } from 'react-i18next';
5 |
6 | i18n
7 | .use(Backend)
8 | .use(LanguageDetector)
9 | .use(reactI18nextModule)
10 | .init({
11 | fallbackLng: 'en',
12 |
13 | // have a common namespace used around the full app
14 | ns: ['translations'],
15 | defaultNS: 'translations',
16 |
17 | debug: true,
18 |
19 | interpolation: {
20 | escapeValue: false, // not needed for react!!
21 | },
22 |
23 | react: {
24 | wait: true
25 | }
26 | });
27 |
28 |
29 | export default i18n;
30 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/pages/_app.js:
--------------------------------------------------------------------------------
1 | import App, { Container } from "next/app";
2 | import { I18n as I18nR } from "react-i18next";
3 | import i18n from "../i18n";
4 |
5 | export default class MyApp extends App {
6 | render() {
7 | const { Component, pageProps } = this.props;
8 | console.warn(pageProps)
9 | return (
10 |
11 |
12 | {
13 | (t) => (
14 |
15 |
{t('common:integrates_react-i18next')}
16 |
17 |
18 | )
19 | }
20 |
21 |
22 | );
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/pages/page2.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Link from 'next/link'
3 |
4 | import PureComponent from '../components/PureComponent'
5 | import ExtendedComponent from '../components/ExtendedComponent'
6 | import ComponentWithTrans from '../components/ComponentWithTrans'
7 | import { withI18next } from '../lib/withI18next'
8 |
9 | const Page2 = ({ t }) => (
10 |
11 |
{t('welcomePage2')}
12 |
{t('common:integrates_react-i18next')}
13 |
14 |
15 |
16 |
17 |
{t('link.gotoPage1')}
18 |
19 |
20 | )
21 |
22 | export default withI18next(['page2', 'common'])(Page2)
23 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-i18next-nextjs-example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "dev": "node server.js",
8 | "build": "next build",
9 | "start": "NODE_ENV=production node server.js"
10 | },
11 | "author": "",
12 | "license": "MIT",
13 | "dependencies": {
14 | "express": "4.16.3",
15 | "i18next": "11.3.6",
16 | "i18next-browser-languagedetector": "2.2.0",
17 | "i18next-express-middleware": "1.2.0",
18 | "i18next-node-fs-backend": "1.2.1",
19 | "i18next-xhr-backend": "1.5.1",
20 | "next": "^6.1.1",
21 | "react": "^16.4.1",
22 | "react-dom": "^16.4.1",
23 | "react-i18next": "7.8.1"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/example/storybook/stories/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf, action, linkTo } from '@storybook/react';
3 | import SayWelcome from './SayWelcome';
4 |
5 | import App from '../src/App';
6 | import { I18nextProvider } from 'react-i18next';
7 | import i18n from '../src/i18n';
8 |
9 | storiesOf('decorated component (having translate hoc)', module)
10 | .addDecorator(story => (
11 |
12 | {story()}
13 |
14 | ))
15 | .add('app view', () => (
16 |
17 | ))
18 |
19 | storiesOf('undecorated component (no translate hoc just t function in props)', module)
20 | .add('showing a pure component', () => (
21 | key} />
22 | ))
23 |
--------------------------------------------------------------------------------
/example/nextjs-locize/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-i18next-nextjs-locize-example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "dev": "node server.js",
8 | "build": "next build",
9 | "start": "NODE_ENV=production node server.js"
10 | },
11 | "author": "",
12 | "license": "MIT",
13 | "dependencies": {
14 | "express": "4.16.2",
15 | "i18next": "10.4.1",
16 | "i18next-browser-languagedetector": "2.1.0",
17 | "i18next-express-middleware": "1.0.10",
18 | "i18next-locize-backend": "1.3.0",
19 | "i18next-node-locize-backend": "2.1.0",
20 | "next": "5.0.0",
21 | "react": "16.2.0",
22 | "react-dom": "16.2.0",
23 | "react-i18next": "7.4.0"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/interpolate.spec.js:
--------------------------------------------------------------------------------
1 | jest.unmock('../src/Interpolate');
2 | import React from 'react';
3 | import PropTypes from 'prop-types';
4 | import Interpolate from '../src/Interpolate';
5 |
6 | describe('interpolate', () => {
7 | it('should have some stuff', () => {
8 | expect(Interpolate.contextTypes.i18n)
9 | .toBe(PropTypes.object.isRequired);
10 | expect(Interpolate.contextTypes.t)
11 | .toBe(PropTypes.func.isRequired);
12 | const props = {};
13 | const context = {
14 | i18n: {},
15 | t(message) {
16 | return message;
17 | }
18 | };
19 | const interpolate = new Interpolate(props, context);
20 | expect(interpolate.i18n).toBe(context.i18n);
21 | expect(interpolate.t).toBe(context.t);
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import Backend from 'i18next-xhr-backend';
3 | import LanguageDetector from 'i18next-browser-languagedetector';
4 | import { reactI18nextModule } from 'react-i18next';
5 |
6 | i18n
7 | .use(Backend)
8 | .use(LanguageDetector)
9 | .use(reactI18nextModule)
10 | .init({
11 | fallbackLng: 'en',
12 |
13 | // have a common namespace used around the full app
14 | ns: ['translations'],
15 | defaultNS: 'translations',
16 |
17 | debug: true,
18 |
19 | interpolation: {
20 | escapeValue: false, // not needed for react!!
21 | },
22 |
23 | react: {
24 | defaultTransParent: 'div', // needed for preact
25 | wait: true
26 | }
27 | });
28 |
29 |
30 | export default i18n;
31 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/lib/withI18next.js:
--------------------------------------------------------------------------------
1 | import { translate, loadNamespaces } from 'react-i18next'
2 | import i18n from '../i18n'
3 |
4 | export const withI18next = (namespaces = ['common']) => ComposedComponent => {
5 | const Extended = translate(namespaces, { i18n, wait: process.browser })(
6 | ComposedComponent
7 | )
8 |
9 | Extended.getInitialProps = async (ctx) => {
10 | const composedInitialProps = ComposedComponent.getInitialProps
11 | ? await ComposedComponent.getInitialProps(ctx)
12 | : {}
13 |
14 | const i18nInitialProps = ctx.req
15 | ? i18n.getInitialProps(ctx.req, namespaces)
16 | : {};
17 |
18 | return {
19 | ...composedInitialProps,
20 | ...i18nInitialProps
21 | }
22 | }
23 |
24 | return Extended
25 | }
26 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import Backend from 'i18next-xhr-backend';
3 | import LanguageDetector from 'i18next-browser-languagedetector';
4 | import { reactI18nextModule } from 'react-i18next';
5 |
6 | i18n
7 | .use(Backend)
8 | .use(LanguageDetector)
9 | .use(reactI18nextModule)
10 | .init({
11 | fallbackLng: 'en',
12 |
13 | // have a common namespace used around the full app
14 | ns: ['translations'],
15 | defaultNS: 'translations',
16 |
17 | debug: true,
18 |
19 | interpolation: {
20 | escapeValue: false, // not needed for react!!
21 | },
22 |
23 | react: {
24 | defaultTransParent: 'div', // needed for preact
25 | wait: true
26 | }
27 | });
28 |
29 |
30 | export default i18n;
31 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import Backend from 'i18next-fluent-backend';
3 | import LanguageDetector from 'i18next-browser-languagedetector';
4 | import { reactI18nextModule } from 'react-i18next';
5 |
6 | import Fluent from 'i18next-fluent';
7 | i18n
8 | .use(Fluent)
9 | .use(Backend)
10 | .use(LanguageDetector)
11 | .use(reactI18nextModule)
12 | .init({
13 | fallbackLng: 'en',
14 |
15 | // have a common namespace used around the full app
16 | ns: ['translations'],
17 | defaultNS: 'translations',
18 |
19 | debug: true,
20 |
21 | interpolation: {
22 | escapeValue: false, // not needed for react!!
23 | },
24 |
25 | react: {
26 | wait: true
27 | }
28 | });
29 |
30 |
31 | export default i18n;
32 |
--------------------------------------------------------------------------------
/src/context.js:
--------------------------------------------------------------------------------
1 | let defaultOptions = {
2 | wait: false,
3 | withRef: false,
4 | bindI18n: 'languageChanged loaded',
5 | bindStore: 'added removed',
6 | translateFuncName: 't',
7 | nsMode: 'default',
8 | usePureComponent: false,
9 | omitBoundRerender: true,
10 | };
11 |
12 | let i18n;
13 |
14 | export function setDefaults(options) {
15 | defaultOptions = { ...defaultOptions, ...options };
16 | }
17 |
18 | export function getDefaults() {
19 | return defaultOptions;
20 | }
21 |
22 | export function setI18n(instance) {
23 | i18n = instance;
24 | }
25 |
26 | export function getI18n() {
27 | return i18n;
28 | }
29 |
30 | export const reactI18nextModule = {
31 | type: '3rdParty',
32 |
33 | init(instance) {
34 | setDefaults(instance.options.react);
35 | setI18n(instance);
36 | },
37 | };
38 |
--------------------------------------------------------------------------------
/example/storybook/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "storybook-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "i18next": "11.3.2",
7 | "i18next-browser-languagedetector": "2.2.0",
8 | "i18next-locize-backend": "1.4.2",
9 | "locize-editor": "1.3.0",
10 | "react": "16.3.2",
11 | "react-dom": "16.3.2",
12 | "react-i18next": "7.6.1",
13 | "react-scripts": "1.1.4"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test --env=jsdom",
19 | "eject": "react-scripts eject",
20 | "storybook": "start-storybook -p 6006",
21 | "build-storybook": "build-storybook"
22 | },
23 | "devDependencies": {
24 | "@storybook/react": "3.4.4",
25 | "babel-core": "6.26.3",
26 | "babel-runtime": "6.26.0"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/example/react_withHOC/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react_withhoc",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^16.4.0",
7 | "react-dom": "^16.4.0",
8 | "react-scripts": "1.1.4",
9 | "i18next": "11.3.2",
10 | "i18next-browser-languagedetector": "2.2.0",
11 | "i18next-xhr-backend": "1.5.1",
12 | "react-i18next": "7.12.0"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test --env=jsdom",
18 | "eject": "react-scripts eject"
19 | },
20 | "browserslist": {
21 | "development": [
22 | "last 2 chrome versions",
23 | "last 2 firefox versions",
24 | "last 2 edge versions"
25 | ],
26 | "production": [
27 | ">1%",
28 | "last 4 versions",
29 | "Firefox ESR",
30 | "not ie < 11"
31 | ]
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/example/react-native-expo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-expo",
3 | "version": "0.1.0",
4 | "private": true,
5 | "devDependencies": {
6 | "react-native-scripts": "1.14.0",
7 | "jest-expo": "27.0.1",
8 | "react-test-renderer": "16.4.0"
9 | },
10 | "main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
11 | "scripts": {
12 | "start": "react-native-scripts start",
13 | "eject": "react-native-scripts eject",
14 | "android": "react-native-scripts android",
15 | "ios": "react-native-scripts ios",
16 | "test": "node node_modules/jest/bin/jest.js --watch"
17 | },
18 | "jest": {
19 | "preset": "jest-expo"
20 | },
21 | "dependencies": {
22 | "expo": "27.0.2",
23 | "react": "16.4.0",
24 | "react-native": "0.55.4",
25 | "i18next": "11.3.2",
26 | "react-i18next": "7.7.0",
27 | "react-navigation": "2.3.0-beta.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/example/locize-example/README.md:
--------------------------------------------------------------------------------
1 | This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
2 |
3 | [](https://www.youtube.com/watch?v=9NOzJhgmyQE)
4 |
5 | [watch the video](https://www.youtube.com/watch?v=9NOzJhgmyQE)
6 |
7 | ## using with locize
8 |
9 | We added our translation management [locize.com](http://locize.com).
10 |
11 | - [locize-editor](https://github.com/locize/locize-editor)
12 | - [i18next-locize-backend](https://github.com/locize/i18next-locize-backend)
13 |
14 | You will find your project informations like projectId and apiKey on your locize projects settings. (Signup add a new project for testing).
15 |
16 | Set projectId and apiKey in `/src/i18n.js`.
17 |
18 | ## start
19 |
20 | ```bash
21 | # npm start
22 | ```
23 |
24 | open `http://localhost:3000?locize=true` to open your application with the locize incontext editor.
25 |
--------------------------------------------------------------------------------
/test/I18n.spec.js:
--------------------------------------------------------------------------------
1 | jest.unmock('../src/I18n');
2 | import I18n from '../src/I18n';
3 |
4 | const i18n = {
5 | language: 'en',
6 | languages: ['en'],
7 | options: {
8 | defaultNS: 'defaultNS'
9 | },
10 | services: {
11 | resourceStore: {
12 | data: {}
13 | }
14 | },
15 | changeLanguage: () => {},
16 | getFixedT: message => message,
17 | hasResourceBundle: (lng, ns) => ns === 'alreadyLoadedNS',
18 | loadNamespaces: () => {}
19 | };
20 |
21 | describe('I18n', () => {
22 | it('sets initial ready state to false if resource bundles are not loaded', () => {
23 | const notLoadedInstance = new I18n({ i18n, ns: ['notLoadedNS', 'alreadyLoadedNS'] }, {});
24 | expect(notLoadedInstance.state.ready).toBe(false);
25 | });
26 |
27 | it('sets initial ready state to true if resource bundles are already loaded', () => {
28 | const notLoadedInstance = new I18n({ i18n, ns: ['alreadyLoadedNS'] }, {});
29 | expect(notLoadedInstance.state.ready).toBe(true);
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import Backend from 'i18next-xhr-backend';
3 | import LanguageDetector from 'i18next-browser-languagedetector';
4 | import { reactI18nextModule } from 'react-i18next';
5 |
6 | import ICU from 'i18next-icu'
7 | import de from 'i18next-icu/locale-data/de'; // or dynamically like: https://github.com/locize/locize-react-intl-example/blob/master/src/locize/index.js#L53
8 |
9 | i18n
10 | .use(new ICU({
11 | localeData: de // you also can pass in array of localeData
12 | }))
13 | .use(Backend)
14 | .use(LanguageDetector)
15 | .use(reactI18nextModule)
16 | .init({
17 | fallbackLng: 'en',
18 |
19 | // have a common namespace used around the full app
20 | ns: ['translations'],
21 | defaultNS: 'translations',
22 |
23 | debug: true,
24 |
25 | interpolation: {
26 | escapeValue: false, // not needed for react!!
27 | },
28 |
29 | react: {
30 | wait: true
31 | }
32 | });
33 |
34 |
35 | export default i18n;
36 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react_icu_withhoc",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "i18next": "11.2.2",
7 | "i18next-browser-languagedetector": "2.1.0",
8 | "i18next-icu": "0.3.0",
9 | "i18next-xhr-backend": "1.5.0",
10 | "react": "^16.0.0",
11 | "react-dom": "^16.0.0",
12 | "react-i18next": "7.10.1",
13 | "react-scripts": "^2.0.0-next.47d2d941"
14 | },
15 | "devDependencies": {
16 | "babel-plugin-macros": "^2.3.0"
17 | },
18 | "scripts": {
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test --env=jsdom",
22 | "eject": "react-scripts eject"
23 | },
24 | "browserslist": {
25 | "development": [
26 | "last 2 chrome versions",
27 | "last 2 firefox versions",
28 | "last 2 edge versions"
29 | ],
30 | "production": [
31 | ">1%",
32 | "last 4 versions",
33 | "Firefox ESR",
34 | "not ie < 11"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/example/razzle-ssr/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "my-razzle-app",
3 | "version": "0.1.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "start": "razzle start",
7 | "build": "razzle build",
8 | "test": "razzle test --env=jsdom",
9 | "start:prod": "NODE_ENV=production node build/server.js"
10 | },
11 | "dependencies": {
12 | "babel-cli": "6.26.0",
13 | "babel-core": "6.26.0",
14 | "babel-eslint": "8.2.6",
15 | "babel-jest": "21.2.0",
16 | "babel-plugin-macros": "^2.3.0",
17 | "babel-preset-es2015": "6.24.1",
18 | "babel-preset-react": "6.24.1",
19 | "babel-preset-stage-0": "6.24.1",
20 | "babel-register": "6.26.0",
21 | "razzle": "2.4.0",
22 | "react": "16.4.1",
23 | "react-dom": "16.4.1",
24 | "react-router-dom": "4.3.1",
25 | "react-i18next": "7.10.1",
26 | "i18next": "11.5.0",
27 | "i18next-browser-languagedetector": "2.2.2",
28 | "i18next-express-middleware": "1.2.0",
29 | "i18next-node-fs-backend": "1.2.1",
30 | "i18next-xhr-backend": "1.5.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react_fluent_withhoc",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "i18next": "11.8.0",
7 | "i18next-browser-languagedetector": "2.1.0",
8 | "i18next-fluent": "0.0.3",
9 | "i18next-fluent-backend": "0.0.2",
10 | "react": "^16.0.0",
11 | "react-dom": "^16.0.0",
12 | "react-i18next": "7.10.1",
13 | "react-scripts": "^2.0.0-next.47d2d941"
14 | },
15 | "devDependencies": {
16 | "babel-plugin-macros": "^2.3.0"
17 | },
18 | "scripts": {
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test --env=jsdom",
22 | "eject": "react-scripts eject"
23 | },
24 | "browserslist": {
25 | "development": [
26 | "last 2 chrome versions",
27 | "last 2 firefox versions",
28 | "last 2 edge versions"
29 | ],
30 | "production": [
31 | ">1%",
32 | "last 4 versions",
33 | "Firefox ESR",
34 | "not ie < 11"
35 | ]
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel';
2 | import uglify from 'rollup-plugin-uglify';
3 | import commonjs from 'rollup-plugin-commonjs';
4 | import nodeResolve from 'rollup-plugin-node-resolve';
5 | import { argv } from 'yargs';
6 |
7 | const format = argv.format || argv.f || 'iife';
8 | const compress = argv.uglify;
9 |
10 | const babelOptions = {
11 | exclude: 'node_modules/**',
12 | presets: ['es2015-rollup', 'stage-0'],
13 | babelrc: false
14 | };
15 |
16 | const dest = {
17 | amd: `dist/amd/react-i18next${compress ? '.min' : ''}.js`,
18 | umd: `dist/umd/react-i18next${compress ? '.min' : ''}.js`,
19 | iife: `dist/iife/react-i18next${compress ? '.min' : ''}.js`
20 | }[format];
21 |
22 | export default {
23 | entry: 'src/index.js',
24 | format,
25 | external: ['react', 'react-dom', 'prop-types'],
26 | plugins: [
27 | babel(babelOptions),
28 | nodeResolve({ jsnext: true }),
29 | commonjs()
30 | ].concat(compress ? uglify() : []),
31 | moduleName: 'reactI18next',
32 | moduleId: 'reactI18next',
33 | dest
34 | };
35 |
--------------------------------------------------------------------------------
/example/nextjs-locize/pages/page2.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Link from 'next/link';
3 | import { translate } from 'react-i18next';
4 | import i18n from '../i18n';
5 |
6 | import PureComponent from '../components/PureComponent';
7 | import ExtendedComponent from '../components/ExtendedComponent';
8 |
9 | function Page2({ t, initialI18nStore }) {
10 | return (
11 |
12 | {t('welcomePage2')}
13 |
{t('common:integrates_react-i18next')}
14 |
15 |
16 |
{t('link.gotoPage1')}
17 |
18 | );
19 | }
20 |
21 | const Extended = translate(['page2', 'common'], { i18n, wait: process.browser })(Page2);
22 |
23 | // Passing down initial translations
24 | // use req.i18n instance on serverside to avoid overlapping requests set the language wrong
25 | Extended.getInitialProps = async ({ req }) => {
26 | if (req && !process.browser) return i18n.getInitialProps(req, ['page2', 'common']);
27 | return {};
28 | };
29 |
30 | export default Extended;
31 |
--------------------------------------------------------------------------------
/example/razzle-ssr/README.md:
--------------------------------------------------------------------------------
1 | # Getting started
2 |
3 | Build with [razzle](https://github.com/jaredpalmer/razzle) using its react ssr.
4 |
5 | ```bash
6 | # npm start
7 | ```
8 |
9 | **open:**
10 |
11 | will detect language: [http://localhost:3000](http://localhost:3000)
12 |
13 | german: [http://localhost:3000/?lng=de](http://localhost:3000/?lng=de)
14 |
15 | english: [http://localhost:3000/?lng=en](http://localhost:3000/?lng=en)
16 |
17 |
18 | ## production
19 | ```bash
20 | # npm run build
21 | # npm run start:prod
22 | ```
23 |
24 | ## Learn more
25 |
26 | - Uses express to also serve translations for clientside
27 | - Translations are passed down to client on initial serverside render -> no reload of translations, no flickering
28 | - Uses *i18next-express-middleware* on the serverside to assert that every request gets his own instance of i18next (no race condition conflicts when user b overrides set language in i18next singleton of user a!!!)
29 | - completely allows saveMissing feature of i18next -> added content will be pushed to server and stored in `xyz.missing.json`
30 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Link from 'next/link'
3 |
4 | import PureComponent from '../components/PureComponent'
5 | import ExtendedComponent from '../components/ExtendedComponent'
6 | import ComponentWithTrans from '../components/ComponentWithTrans'
7 | import { withI18next } from '../lib/withI18next'
8 |
9 | const TestContent = withI18next(['home', 'common'])(({ t, initialI18nStore }) => (
10 |
11 |
{t('welcome')}
12 |
{t('common:integrates_react-i18next')}
13 |
{t('sample_test')}
14 |
15 | {t('sample_button')}
16 |
17 |
18 |
19 |
20 |
21 |
{t('link.gotoPage2')}
22 |
23 |
24 |
25 |
{t('link.gotoPage3')}
26 |
27 |
28 | ))
29 |
30 |
31 | const Test = () => {
32 | return(
33 |
34 | )
35 | }
36 |
37 | export default Test;
38 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/App.js:
--------------------------------------------------------------------------------
1 | import { h, Component } from 'preact';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | const { t, i18n } = this.props;
9 |
10 | const changeLanguage = (lng) => {
11 | i18n.changeLanguage(lng);
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
{t('title')}
19 |
changeLanguage('de')}>de
20 |
changeLanguage('en')}>en
21 |
22 |
23 |
24 | To get started, edit src/App.js and save to reload.
25 |
26 |
27 |
{t('description.part2')}
28 |
29 | );
30 | }
31 | }
32 |
33 | export default translate('translations')(App);
34 |
--------------------------------------------------------------------------------
/example/react_withHOC/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | const { t, i18n } = this.props;
9 |
10 | const changeLanguage = (lng) => {
11 | i18n.changeLanguage(lng);
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
{t('title')}
19 |
changeLanguage('de')}>de
20 |
changeLanguage('en')}>en
21 |
22 |
23 |
24 | To get started, edit src/App.js and save to reload.
25 |
26 |
27 |
{t('description.part2')}
28 |
29 | );
30 | }
31 | }
32 |
33 | export default translate('translations')(App);
34 |
--------------------------------------------------------------------------------
/example/storybook/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | const { t, i18n } = this.props;
9 |
10 | const changeLanguage = (lng) => {
11 | i18n.changeLanguage(lng);
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
{t('Welcome to React')}
19 |
changeLanguage('de')}>de
20 |
changeLanguage('en')}>en
21 |
22 |
23 |
24 | To get started, edit src/App.js and save to reload.
25 |
26 |
27 |
{t('will be added automatically to locize.')}
28 |
29 | );
30 | }
31 | }
32 |
33 | export default translate('translations')(App);
34 |
--------------------------------------------------------------------------------
/example/locize-example/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | const { t, i18n } = this.props;
9 |
10 | const changeLanguage = (lng) => {
11 | i18n.changeLanguage(lng);
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
{t('Welcome to React')}
19 |
changeLanguage('de')}>de
20 |
changeLanguage('en')}>en
21 |
22 |
23 |
24 | To get started, edit src/App.js and save to reload.
25 |
26 |
27 |
{t('will be added automatically to locize.')}
28 |
29 | );
30 | }
31 | }
32 |
33 | export default translate('translations')(App);
34 |
--------------------------------------------------------------------------------
/example/react-native-expo/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { translate } from 'react-i18next';
3 | import { createStackNavigator } from 'react-navigation';
4 | import i18n from './js/i18n';
5 | import Home from './js/pages/Home';
6 | import Page2 from './js/pages/Page2';
7 |
8 | const Stack = createStackNavigator({
9 | Home: { screen: Home },
10 | Page2: { screen: Page2 }
11 | });
12 |
13 | // Wrapping a stack with translation hoc asserts we get new render on language change
14 | // the hoc is set to only trigger rerender on languageChanged
15 | const WrappedStack = ({t}) => {
16 | return ;
17 | }
18 | const ReloadAppOnLanguageChange = translate('common', {
19 | bindI18n: 'languageChanged',
20 | bindStore: false
21 | })(WrappedStack);
22 |
23 | // The entry point using a react navigation stack navigation
24 | // gets wrapped by the I18nextProvider enabling using translations
25 | // https://github.com/i18next/react-i18next#i18nextprovider
26 | export default class App extends React.Component {
27 | render() {
28 | return ;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/example/test-jest/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | import MyComponent from './MyComponent';
7 |
8 | class App extends Component {
9 | render() {
10 | const { t, i18n } = this.props;
11 |
12 | const changeLanguage = (lng) => {
13 | i18n.changeLanguage(lng);
14 | }
15 |
16 | return (
17 |
18 |
19 |
20 |
{t('title')}
21 |
changeLanguage('de')}>de
22 |
changeLanguage('en')}>en
23 |
24 |
25 |
26 | To get started, edit src/App.js and save to reload.
27 |
28 |
29 |
30 |
31 | );
32 | }
33 | }
34 |
35 | export default translate('translations')(App);
36 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/App.js:
--------------------------------------------------------------------------------
1 | import { h, Component } from 'preact';
2 | import { I18n, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | export default class App extends Component {
7 | render() {
8 | return (
9 |
10 | {
11 | (t, { i18n }) => (
12 |
13 |
14 |
15 |
{t('title')}
16 |
i18n.changeLanguage('de')}>de
17 |
i18n.changeLanguage('en')}>en
18 |
19 |
20 |
21 | To get started, edit src/App.js and save to reload.
22 |
23 |
24 |
{t('description.part2')}
25 |
26 | )
27 | }
28 |
29 | );
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/example/react_renderProps/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { I18n, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | return (
9 |
10 | {
11 | (t, { i18n }) => (
12 |
13 |
14 |
15 |
{t('title')}
16 |
i18n.changeLanguage('de')}>de
17 |
i18n.changeLanguage('en')}>en
18 |
19 |
20 |
21 | To get started, edit src/App.js and save to reload.
22 |
23 |
24 |
{t('description.part2')}
25 |
26 | )
27 | }
28 |
29 | );
30 | }
31 | }
32 |
33 | export default App;
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 i18next
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/example/nextjs-locize/pages/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Link from 'next/link';
3 | import { translate } from 'react-i18next';
4 | import i18n from '../i18n';
5 |
6 | import PureComponent from '../components/PureComponent';
7 | import ExtendedComponent from '../components/ExtendedComponent';
8 |
9 | function Home({ t, initialI18nStore }) {
10 | return (
11 |
20 | );
21 | }
22 |
23 | const Extended = translate(['home', 'common'], { i18n, wait: process.browser })(Home);
24 |
25 | // Passing down initial translations
26 | // use req.i18n instance on serverside to avoid overlapping requests set the language wrong
27 | Extended.getInitialProps = async ({ req }) => {
28 | if (req && !process.browser) return i18n.getInitialProps(req, ['home', 'common']);
29 | return {};
30 | };
31 |
32 | export default Extended;
33 |
--------------------------------------------------------------------------------
/test/i18n.render.spec.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { mount } from 'enzyme';
3 | import i18n from './i18n';
4 | import I18n from '../src/I18n';
5 |
6 | const context = { i18n };
7 |
8 | describe('I18n', () => {
9 | it('should render correct content', () => {
10 | const wrapper = mount(
11 | {t => {t('key1')} } ,
12 | { context }
13 | );
14 |
15 | expect(wrapper.contains(test )).toBe(true);
16 | });
17 |
18 | it('should render correct content for a component that renders a component', () => {
19 | const Comp = () => (
20 |
21 | Values:
22 |
23 | {t => (
24 |
25 | {t('key1')}
26 | {t('key1')}
27 |
28 | )}
29 |
30 |
31 | );
32 |
33 | const wrapper = mount( , { context });
34 |
35 | expect(
36 | wrapper.contains(
37 |
38 | test
39 | test
40 |
41 | )
42 | ).toBe(true);
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/i18n.js:
--------------------------------------------------------------------------------
1 | const i18n = require('i18next');
2 | const XHR = require('i18next-xhr-backend');
3 | const LanguageDetector = require('i18next-browser-languagedetector');
4 |
5 | const options = {
6 | fallbackLng: 'en',
7 | load: 'languageOnly', // we only provide en, de -> no region specific locals like en-US, de-DE
8 |
9 | // have a common namespace used around the full app
10 | ns: ['translations'],
11 | defaultNS: 'translations',
12 |
13 | saveMissing: true,
14 | debug: true,
15 |
16 | // cache: {
17 | // enabled: true
18 | // },
19 |
20 | interpolation: {
21 | escapeValue: false, // not needed for react!!
22 | formatSeparator: ',',
23 | format: (value, format, lng) => {
24 | if (format === 'uppercase') return value.toUpperCase();
25 | return value;
26 | },
27 | },
28 | wait: process && !process.release,
29 | };
30 |
31 | // for browser use xhr backend to load translations and browser lng detector
32 | if (process && !process.release) {
33 | i18n
34 | .use(XHR)
35 | // .use(Cache)
36 | .use(LanguageDetector);
37 | }
38 |
39 | // initialize if not already initialized
40 | if (!i18n.isInitialized) i18n.init(options);
41 |
42 | module.exports = i18n;
43 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | const { t, i18n } = this.props;
9 |
10 | const changeLanguage = (lng) => {
11 | i18n.changeLanguage(lng);
12 | }
13 |
14 | return (
15 |
16 |
17 |
18 |
{t('title')}
19 |
changeLanguage('de')}>de
20 |
changeLanguage('en')}>en
21 |
22 |
23 |
24 | To get started, edit src/App.js and save to reload.
25 |
26 |
27 |
{t('description_2')}
28 |
29 | You have one unread email.
30 |
31 |
32 | );
33 | }
34 | }
35 |
36 | export default translate('translations')(App);
37 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/Home.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './react.svg';
4 | import './Home.css';
5 |
6 | class Home extends Component {
7 | render() {
8 | const { t } = this.props;
9 |
10 | return (
11 |
12 |
13 |
14 |
{t('message.welcome')}
15 |
16 |
17 |
18 | To get started, edit src/App.js or src/Home.js and save to
19 | reload.
20 |
21 |
22 |
33 |
34 | );
35 | }
36 | }
37 |
38 | export default translate('translations')(Home);
39 |
--------------------------------------------------------------------------------
/test/translate.render.spec.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow, render, mount } from 'enzyme';
3 | import i18n from './i18n';
4 | import translate from '../src/translate';
5 |
6 | const context = {
7 | i18n,
8 | };
9 |
10 | describe('translate', () => {
11 | const TestElement = ({ t, lng }) => (
12 |
13 | {t('key1')} - {lng}
14 |
15 | );
16 |
17 | it('should render correct translation', () => {
18 | const HocElement = translate(['translation'], {})(TestElement);
19 |
20 | const wrapper = mount( , { context });
21 | // console.log(wrapper.debug());
22 | expect(wrapper.contains(test - en
)).toBe(true);
23 | });
24 |
25 | it('should bind / unbind', () => {
26 | const HocElement = translate(['translation'], {})(TestElement);
27 |
28 | const wrapper = mount( , context);
29 | // console.log(wrapper.debug());
30 |
31 | // has bound events
32 | expect(i18n.observers.languageChanged.length).toBe(2);
33 | expect(i18n.observers.loaded.length).toBe(2);
34 |
35 | // unbind after unmount
36 | wrapper.unmount();
37 | expect(i18n.observers.languageChanged.length).toBe(1);
38 | expect(i18n.observers.loaded.length).toBe(1);
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/example/storybook/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import LocizeBackend from 'i18next-locize-backend';
3 | import LocizeEditor from 'locize-editor';
4 | import LanguageDetector from 'i18next-browser-languagedetector';
5 |
6 | i18n
7 | .use(LocizeBackend)
8 | .use(LocizeEditor)
9 | .use(LanguageDetector)
10 | .init({
11 | fallbackLng: 'en',
12 | appendNamespaceToCIMode: true,
13 | saveMissing: true,
14 |
15 | // have a common namespace used around the full app
16 | ns: ['translations'],
17 | defaultNS: 'translations',
18 |
19 | debug: true,
20 | keySeparator: '### not used ###', // we use content as keys
21 | nsSeparator: '### not used ###', // we use content as keys
22 |
23 | backend: {
24 | projectId: 'e365e54a-c52c-479b-8538-682635db252f', // <-- replace with your projectId
25 | apiKey: 'your apiKey',
26 | referenceLng: 'en',
27 | },
28 |
29 | interpolation: {
30 | escapeValue: false, // not needed for react!!
31 | formatSeparator: ',',
32 | format(value, format, lng) {
33 | if (format === 'uppercase') return value.toUpperCase();
34 | return value;
35 | },
36 | },
37 |
38 | react: {
39 | wait: true,
40 | },
41 | });
42 |
43 | export default i18n;
44 |
--------------------------------------------------------------------------------
/test/loadNamespaces.spec.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | jest.unmock('../src/loadNamespaces');
3 |
4 | import loadNamespaces from '../src/loadNamespaces';
5 |
6 | describe('translate', () => {
7 | it('should return a Promise', () => {
8 | const promise = loadNamespaces({ components: [], i18n: {} });
9 | expect(typeof promise.then).toBe('function');
10 | });
11 | it('should preload all namespaces', (done) => {
12 | const i18n = {
13 | loadNamespaces(namespaces, resolve) {
14 | expect(Array.isArray(namespaces));
15 | expect(typeof resolve).toBe('function');
16 | return resolve(namespaces);
17 | }
18 | };
19 | function C1() {}
20 | C1.namespaces = ['ns1'];
21 | function C2() {}
22 | C2.namespaces = ['ns21', 'ns22'];
23 | const C3 = React.createFactory('Elem');
24 | C3.namespaces = ['ns31'];
25 | const C4 = { element: { namespaces: ['ns41'] } }
26 | const components = [C1, C2, C3, C4];
27 | const promise = loadNamespaces({ components, i18n });
28 | promise.then((data) => {
29 | expect(data.length).toBe(5);
30 | expect(data[0]).toBe('ns1');
31 | expect(data[1]).toBe('ns21');
32 | expect(data[2]).toBe('ns22');
33 | expect(data[3]).toBe('ns31');
34 | expect(data[4]).toBe('ns41');
35 | done();
36 | });
37 | });
38 | });
39 |
--------------------------------------------------------------------------------
/example/dat/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { I18nextProvider } from 'react-i18next';
4 |
5 | import './index.css';
6 | import App from './App';
7 | import i18n from './i18n';
8 | import registerServiceWorker from './registerServiceWorker';
9 | import whichBackend from './whichBackend';
10 |
11 | function render() {
12 | ReactDOM.render( , document.getElementById('root'));
13 | registerServiceWorker();
14 | }
15 |
16 | if (whichBackend() === 'locize' && navigator && navigator.permissions && navigator.permissions.request) {
17 | const permission = {
18 | name: 'network',
19 | hostname: 'api.locize.io'
20 | };
21 |
22 | navigator.permissions.query(permission).then((res) => {
23 | if (res.state === 'granted') return render();
24 |
25 | navigator.permissions.request(permission).then((res) => {
26 | if (res.state === 'granted') return document.location.reload();
27 | console.error('not allowed to access the "api.locize.io" network');
28 | });
29 | });
30 | } else if (whichBackend() === 'locize' && document.location.href.indexOf('https://') === 0 && document.location.hostname.indexOf('hashbase.io') > 0) {
31 | document.location = document.location.href.replace('https://', 'dat://');
32 | } else {
33 | render();
34 | }
35 |
--------------------------------------------------------------------------------
/example/react-native-expo/js/pages/Page2.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import { StyleSheet, Text, View, Button } from 'react-native';
4 |
5 |
6 | export class Page2 extends React.Component {
7 | static navigationOptions = ({ navigation, screenProps }) => ({
8 | title: screenProps.t('page2:title')
9 | });
10 |
11 | render() {
12 | const { t, i18n } = this.props;
13 |
14 | return (
15 |
16 | {t('introduction')}
17 | {t('common:currentLanguage', { lng: i18n.language })}
18 |
19 |
20 | One
21 | Two
22 | Three
23 | Four
24 | Five
25 |
26 |
27 |
28 | );
29 | }
30 | }
31 |
32 | export default translate(['page2', 'common'], { wait: true })(Page2);
33 |
34 | const styles = StyleSheet.create({
35 | container: {
36 | flex: 1,
37 | backgroundColor: '#fff',
38 | alignItems: 'center',
39 | justifyContent: 'center',
40 | },
41 | bold: {
42 | fontWeight: 'bold'
43 | },
44 | light: {
45 | fontWeight: 'normal'
46 | }
47 | });
48 |
--------------------------------------------------------------------------------
/example/dat/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | class App extends Component {
7 | render() {
8 | const { t, i18n } = this.props;
9 |
10 | const changeLanguage = (lng) => {
11 | i18n.changeLanguage(lng);
12 | }
13 |
14 | let url = window.location.origin + '?backend=locize';
15 |
16 | if (document.location.href.indexOf('https://') === 0 && document.location.hostname.indexOf('hashbase.io') > 0) {
17 | url = window.location.origin + '?backend=xhr';
18 | }
19 |
20 | return (
21 |
22 |
23 |
24 |
{t('Welcome to React')}
25 |
changeLanguage('de')}>de
26 |
changeLanguage('en')}>en
27 |
28 |
29 |
30 | To get started, edit src/App.js and save to reload.
31 |
32 |
33 |
34 |
GitHub
35 |
36 | );
37 | }
38 | }
39 |
40 | export default translate('translations')(App);
41 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { translate, Trans } from 'react-i18next';
3 | import logo from './logo.svg';
4 | import './App.css';
5 |
6 | import ComponentUsingMacro from './ComponentUsingMacro';
7 |
8 | class App extends Component {
9 | render() {
10 | const { t, i18n } = this.props;
11 |
12 | const changeLanguage = (lng) => {
13 | i18n.changeLanguage(lng);
14 | }
15 |
16 | return (
17 |
18 |
19 |
20 |
{t('title')}
21 |
changeLanguage('de')}>de
22 |
changeLanguage('en')}>en
23 |
24 |
25 |
26 | To get started, edit src/App.js and save to reload.
27 |
28 |
29 |
{t('description.part2')}
30 |
31 |
dummy]}
35 | values={{ numPersons: 1000 }}
36 | />
37 | {t('icu', { numPersons: 500 })}
38 |
39 |
40 | );
41 | }
42 | }
43 |
44 | export default translate('translations')(App);
45 |
--------------------------------------------------------------------------------
/src/loadNamespaces.js:
--------------------------------------------------------------------------------
1 | const objectEntries = Object.entries ||
2 | function( obj ){
3 | var ownProps = Object.keys( obj ),
4 | i = ownProps.length,
5 | resArray = new Array(i); // preallocate the Array
6 | while (i--)
7 | resArray[i] = [ownProps[i], obj[ownProps[i]]];
8 |
9 | return resArray;
10 | };
11 |
12 | // Borrowed from https://github.com/Rezonans/redux-async-connect/blob/master/modules/ReduxAsyncConnect.js#L16
13 | function eachComponents(components, iterator) {
14 | for (let i = 0, l = components.length; i < l; i++) { // eslint-disable-line id-length
15 | if (typeof components[i] === 'object') {
16 | for (const [key, value] of objectEntries(components[i])) {
17 | iterator(value, i, key);
18 | }
19 | } else {
20 | iterator(components[i], i);
21 | }
22 | }
23 | }
24 |
25 | function filterAndFlattenComponents(components) {
26 | const flattened = [];
27 | eachComponents(components, (Component) => {
28 | if (Component && Component.namespaces) {
29 |
30 | Component.namespaces.forEach((namespace) => {
31 | if (flattened.indexOf(namespace) === -1) {
32 | flattened.push(namespace);
33 | }
34 | });
35 | }
36 | });
37 | return flattened;
38 | }
39 |
40 | export default function loadNamespaces({ components, i18n }) {
41 | const allNamespaces = filterAndFlattenComponents(components);
42 |
43 | return new Promise((resolve) => {
44 | i18n.loadNamespaces(allNamespaces, resolve);
45 | });
46 | }
47 |
--------------------------------------------------------------------------------
/example/nextjs-locize/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const next = require('next');
3 |
4 | const dev = process.env.NODE_ENV !== 'production';
5 | const app = next({ dev });
6 | const handle = app.getRequestHandler();
7 |
8 | const i18nextMiddleware = require('i18next-express-middleware');
9 | const locizeBackend = require('i18next-node-locize-backend');
10 | const i18n = require('./i18n');
11 | const locizeOptions = require('./locizeOptions.json');
12 |
13 | locizeOptions.reloadInterval = dev ? 5 * 1000 : 60 * 60 * 1000;
14 |
15 | // init i18next with serverside settings
16 | // using i18next-express-middleware
17 | i18n
18 | .use(locizeBackend)
19 | .use(i18nextMiddleware.LanguageDetector)
20 | .init({
21 | fallbackLng: 'en',
22 | preload: ['en', 'de'], // preload all langages
23 | ns: ['common', 'home', 'page2'], // need to preload all the namespaces
24 | saveMissing: true,
25 | backend: locizeOptions
26 | }, (err) => {
27 | if (err) return console.error(err);
28 |
29 | // loaded translations we can bootstrap our routes
30 | app.prepare().then(() => {
31 | const server = express()
32 |
33 | // enable middleware for i18next
34 | server.use(i18nextMiddleware.handle(i18n));
35 |
36 | // use next.js
37 | server.get('*', (req, res) => handle(req, res))
38 |
39 | server.listen(3000, (err) => {
40 | if (err) return console.error(err);
41 | console.log('> Ready on http://localhost:3000')
42 | });
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/test/interpolate.render.spec.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow, render, mount } from 'enzyme';
3 | import i18n from './i18n';
4 | import translate from '../src/translate';
5 | import Interpolate from '../src/Interpolate';
6 |
7 | const context = {
8 | i18n
9 | };
10 |
11 | describe('interpolate', () => {
12 | const TestElement = ({ t }) => {
13 | return (
14 | something} up="uppercase" />
15 | );
16 | }
17 |
18 | it('should render correct interpolation', () => {
19 | const HocElement = translate(['translation'], {})(TestElement);
20 |
21 | const wrapper = mount( , { context });
22 | // console.log(wrapper.debug());
23 | expect(wrapper.contains(add something UPPERCASE
)).toBe(true);
24 | });
25 | });
26 |
27 | describe('interpolate dangerouslySetInnerHTML', () => {
28 | const TestElement = ({ t }) => {
29 | return (
30 | something} up="uppercase" />
31 | );
32 | }
33 |
34 | it('should render correct interpolation', () => {
35 | const HocElement = translate(['translation'], {})(TestElement);
36 |
37 | const wrapper = mount( , { context });
38 | // console.log(wrapper.debug());
39 | expect(wrapper.contains(add ' }} />something UPPERCASE
)).toBe(true);
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/test/translate.render.nsMode.spec.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow, render, mount } from 'enzyme';
3 | import i18n from './i18n';
4 | import translate from '../src/translate';
5 |
6 | const newI18n = i18n.createInstance();
7 | newI18n
8 | .init({
9 | lng: 'en',
10 | fallbackLng: 'en',
11 |
12 | resources: {
13 | en: {
14 | a: {
15 | key1: 'test a',
16 | },
17 | b: {
18 | key2: 'test b'
19 | }
20 | }
21 | },
22 |
23 | interpolation: {
24 | escapeValue: false, // not needed for react!!
25 | }
26 | })
27 |
28 | const context = {
29 | i18n: newI18n
30 | };
31 |
32 | describe.only('translate wait', () => {
33 | const TestElement = ({ t }) => {
34 | return (
35 | {t('key2')}
36 | );
37 | }
38 |
39 | it('should fallback for correct translation', () => {
40 | const HocElement = translate(['a', 'b'], { nsMode: 'fallback' })(TestElement);
41 |
42 | const wrapper = mount( , { context });
43 | // console.log(wrapper.debug());
44 | expect(wrapper.contains(test b
)).toBe(true);
45 | });
46 |
47 |
48 | it('should global wait for correct translation', () => {
49 | // reinit global
50 | newI18n.init({ react: { nsMode: 'fallback' }});
51 |
52 | const HocElement = translate(['a', 'b'], { /*nsMode: fallback*/ })(TestElement);
53 |
54 | const wrapper = mount( , { context });
55 | // console.log(wrapper.debug());
56 | expect(wrapper.contains(test b
)).toBe(true);
57 | });
58 | });
59 |
--------------------------------------------------------------------------------
/example/locize-example/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import LocizeBackend from 'i18next-locize-backend';
3 | import LocizeEditor from 'locize-editor';
4 | import LanguageDetector from 'i18next-browser-languagedetector';
5 | import { reactI18nextModule } from 'react-i18next';
6 |
7 |
8 | i18n
9 | .use(LocizeBackend)
10 | .use(LocizeEditor)
11 | .use(LanguageDetector)
12 | .use(reactI18nextModule)
13 | .init({
14 | fallbackLng: 'en',
15 | appendNamespaceToCIMode: true,
16 | saveMissing: true,
17 |
18 | // have a common namespace used around the full app
19 | ns: ['translations'],
20 | defaultNS: 'translations',
21 |
22 | debug: true,
23 | keySeparator: '### not used ###', // we use content as keys
24 | nsSeparator: '### not used ###', // we use content as keys
25 |
26 | backend: {
27 | projectId: 'e365e54a-c52c-479b-8538-682635db252f', // <-- replace with your projectId
28 | apiKey: '74c6a6a6-5c81-49d8-b4d1-cd8fdc76b5e2',
29 | referenceLng: 'en'
30 | },
31 |
32 | interpolation: {
33 | escapeValue: false, // not needed for react!!
34 | formatSeparator: ',',
35 | format: function(value, format, lng) {
36 | if (format === 'uppercase') return value.toUpperCase();
37 | return value;
38 | }
39 | },
40 |
41 | react: {
42 | wait: true
43 | },
44 |
45 | editor: {
46 | // trigger a reload on editor save
47 | onEditorSaved: function(lng, ns) {
48 | i18n.reloadResources(lng, ns);
49 | }
50 | }
51 | });
52 |
53 |
54 | export default i18n;
55 |
--------------------------------------------------------------------------------
/example/react-native-expo/js/pages/Home.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { translate } from 'react-i18next';
3 | import { StyleSheet, Text, View, Button } from 'react-native';
4 |
5 | // using the translation hoc to provie t function in props using home as default namespace
6 | // https://github.com/i18next/react-i18next#translate-hoc
7 | export class Home extends React.Component {
8 | static navigationOptions = ({ navigation, screenProps }) => ({
9 | title: screenProps.t('home:title')
10 | });
11 |
12 | render() {
13 | const { t, i18n, navigation } = this.props;
14 | const { navigate } = navigation;
15 |
16 | return (
17 |
18 | {t('common:currentLanguage', { lng: i18n.language })}
19 | { i18n.changeLanguage('en') }}
21 | title={t('common:actions.toggleToEnglish')}
22 | />
23 | { i18n.changeLanguage('de') }}
25 | title={t('common:actions.toggleToGerman')}
26 | />
27 | {t('introduction')}
28 | navigate('Page2')}
30 | title={t('common:actions.goToPage2')}
31 | />
32 |
33 | );
34 | }
35 | }
36 |
37 | export default translate(['home', 'common'], { wait: true })(Home);
38 |
39 | const styles = StyleSheet.create({
40 | container: {
41 | flex: 1,
42 | backgroundColor: '#fff',
43 | alignItems: 'center',
44 | justifyContent: 'center',
45 | },
46 | separate: {
47 | marginTop: 50
48 | }
49 | });
50 |
--------------------------------------------------------------------------------
/src/I18nextProvider.js:
--------------------------------------------------------------------------------
1 | import { Component, Children } from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | class I18nextProvider extends Component {
5 | constructor(props, context) {
6 | super(props, context);
7 | this.i18n = props.i18n;
8 | this.defaultNS = props.defaultNS;
9 | if (props.initialI18nStore) {
10 | this.i18n.services.resourceStore.data = props.initialI18nStore;
11 | this.i18n.options.isInitialSSR = true; // if set will be deleted on first render in translate hoc
12 | }
13 | if (props.initialLanguage) {
14 | this.i18n.changeLanguage(props.initialLanguage);
15 | }
16 | this.reportNS = props.reportNS;
17 | }
18 |
19 | getChildContext() {
20 | return {
21 | i18n: this.i18n,
22 | defaultNS: this.defaultNS,
23 | reportNS: this.reportNS
24 | };
25 | }
26 |
27 | componentWillReceiveProps(nextProps) {
28 | if (this.props.i18n !== nextProps.i18n) {
29 | throw new Error('[react-i18next][I18nextProvider]does not support changing the i18n object.');
30 | }
31 | }
32 |
33 | render() {
34 | const { children } = this.props;
35 | return Children.only(children);
36 | }
37 | }
38 |
39 | I18nextProvider.propTypes = {
40 | i18n: PropTypes.object.isRequired,
41 | children: PropTypes.element.isRequired,
42 | defaultNS: PropTypes.string,
43 | reportNS: PropTypes.func
44 | };
45 |
46 | I18nextProvider.childContextTypes = {
47 | i18n: PropTypes.object.isRequired,
48 | defaultNS: PropTypes.string,
49 | reportNS: PropTypes.func
50 | };
51 |
52 | I18nextProvider.defaultProps = {
53 | defaultNS: undefined,
54 | reportNS: undefined
55 | };
56 |
57 | export default I18nextProvider;
58 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | const path = require('path')
3 | const next = require('next')
4 |
5 | const dev = process.env.NODE_ENV !== 'production'
6 | const app = next({ dev })
7 | const handle = app.getRequestHandler()
8 |
9 | const i18nextMiddleware = require('i18next-express-middleware')
10 | const Backend = require('i18next-node-fs-backend')
11 | const i18n = require('./i18n')
12 |
13 | // init i18next with serverside settings
14 | // using i18next-express-middleware
15 | i18n
16 | .use(Backend)
17 | .use(i18nextMiddleware.LanguageDetector)
18 | .init({
19 | fallbackLng: 'en',
20 | preload: ['en', 'de'], // preload all langages
21 | ns: ['common', 'home', 'page2'], // need to preload all the namespaces
22 | backend: {
23 | loadPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.json'),
24 | addPath: path.join(__dirname, '/locales/{{lng}}/{{ns}}.missing.json')
25 | }
26 | }, () => {
27 | // loaded translations we can bootstrap our routes
28 | app.prepare()
29 | .then(() => {
30 | const server = express()
31 |
32 | // enable middleware for i18next
33 | server.use(i18nextMiddleware.handle(i18n))
34 |
35 | // serve locales for client
36 | server.use('/locales', express.static(path.join(__dirname, '/locales')))
37 |
38 | // missing keys
39 | server.post('/locales/add/:lng/:ns', i18nextMiddleware.missingKeyHandler(i18n))
40 |
41 | // use next.js
42 | server.get('*', (req, res) => handle(req, res))
43 |
44 | server.listen(3000, (err) => {
45 | if (err) throw err
46 | console.log('> Ready on http://localhost:3000')
47 | })
48 | })
49 | })
50 |
--------------------------------------------------------------------------------
/example/dat/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/test/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 |
3 |
4 | i18n
5 | .init({
6 | lng: 'en',
7 | fallbackLng: 'en',
8 |
9 | resources: {
10 | en: {
11 | translation: {
12 | key1: 'test',
13 | interpolateKey: 'add {{insert}} {{up, uppercase}}',
14 | interpolateKey2: 'add {{insert}} {{up, uppercase}}',
15 | transTest1: "Go <1>there1>.",
16 | transTest1_noParent: "<0>Go <1>there1>.0>",
17 | transTest1_customHtml: "Go <1>there1>.",
18 | transTest2: "Hello <1><0>{{name}}0>1>, you have <3>{{count}}3> message. Open <5>hear5>.",
19 | transTest2_plural: "Hello <1><0>{{name}}0>1>, you have <3>{{count}}3> messages. Open <5>here5>.",
20 | testTransKey1: "<0>{{numOfItems}}0> item matched.",
21 | testTransKey1_plural: "<0>{{numOfItems}}0> items matched.",
22 | testTransKey2: "<0><0>{{numOfItems}}0>0> item matched.",
23 | testTransKey2_plural: "<0><0>{{numOfItems}}0>0> items matched.",
24 | testTransKey3: "Result: <1><0>{{numOfItems}}0>1> item matched.",
25 | testTransKey3_plural: "Result: <1><0>{{numOfItems}}0>1> items matched."
26 | },
27 | other: {
28 | transTest1: "Another go <1>there1>.",
29 | }
30 | }
31 | },
32 |
33 | interpolation: {
34 | escapeValue: false, // not needed for react!!
35 | formatSeparator: ',',
36 | format: function(value, format, lng) {
37 | if (format === 'uppercase') return value.toUpperCase();
38 | return value;
39 | }
40 | },
41 |
42 | react: {
43 | defaultTransParent: 'div'
44 | }
45 | });
46 |
47 |
48 | export default i18n;
49 |
--------------------------------------------------------------------------------
/example/storybook/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/test-jest/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/locize-example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/preact_withHOC/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/react_withHOC/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/preact_renderProps/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/example/react_renderProps/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
26 | You need to enable JavaScript to run this app.
27 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/test/translate.render.wait.spec.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { shallow, render, mount } from 'enzyme';
3 | import i18n from './i18n';
4 | import BackendMock from './backendMock';
5 | import translate from '../src/translate';
6 |
7 | const newI18n = i18n.createInstance();
8 | const backend = new BackendMock();
9 | newI18n
10 | .use(backend)
11 | .init({
12 | lng: 'en',
13 | fallbackLng: 'en',
14 |
15 | interpolation: {
16 | escapeValue: false, // not needed for react!!
17 | }
18 | })
19 |
20 | const context = {
21 | i18n: newI18n
22 | };
23 |
24 | describe('translate wait', () => {
25 | const TestElement = ({ t }) => {
26 | return (
27 | {t('key1')}
28 | );
29 | }
30 |
31 | it('should wait for correct translation', () => {
32 | const HocElement = translate(['common'], { wait: true })(TestElement);
33 |
34 | const wrapper = mount( , { context });
35 | // console.log(wrapper.debug());
36 | expect(wrapper.contains(test
)).toBe(false);
37 |
38 | backend.flush();
39 | wrapper.update();
40 |
41 | setTimeout(() => {
42 | expect(wrapper.contains(test
)).toBe(true);
43 | }, 50);
44 | });
45 |
46 |
47 | it('should global wait for correct translation', () => {
48 | // reinit global
49 | newI18n.init({ react: { wait: true }});
50 |
51 | const HocElement = translate(['common'], { /* not use this -> wait: true */ })(TestElement);
52 |
53 | const wrapper = mount( , { context });
54 | // console.log(wrapper.debug());
55 | expect(wrapper.contains(test
)).toBe(false);
56 |
57 | backend.flush();
58 | wrapper.update();
59 |
60 | setTimeout(() => {
61 | expect(wrapper.contains(test
)).toBe(true);
62 | }, 50);
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/example/test-jest/__mocks__/react-i18next.js:
--------------------------------------------------------------------------------
1 | const React = require('react');
2 | const reactI18next = require('react-i18next');
3 |
4 | const hasChildren = node =>
5 | node && (node.children || (node.props && node.props.children));
6 |
7 | const getChildren = node =>
8 | (node && node.children ? node.children : node.props && node.props.children);
9 |
10 | const renderNodes = (reactNodes) => {
11 | if (typeof reactNodes === 'string') {
12 | return reactNodes;
13 | }
14 |
15 | return Object.keys(reactNodes).map((key, i) => {
16 | const child = reactNodes[key];
17 | const isElement = React.isValidElement(child);
18 |
19 | if (typeof child === 'string') {
20 | return child;
21 | } else if (hasChildren(child)) {
22 | const inner = renderNodes(getChildren(child));
23 | return React.cloneElement(
24 | child,
25 | { ...child.props, key: i },
26 | inner,
27 | );
28 | } else if (typeof child === 'object' && !isElement) {
29 | return Object.keys(child).reduce((str, childKey) => `${str}${child[childKey]}`, '');
30 | }
31 |
32 | return child;
33 | });
34 | };
35 |
36 | module.exports = {
37 | // this mock makes sure any components using the translate HoC receive the t function as a prop
38 | translate: () => Component => props => k} {...props} />,
39 | Trans: ({ children }) => renderNodes(children),
40 | I18n: ({ children }) => children(k => k, { i18n: {} }),
41 |
42 | // mock if needed
43 | Interpolate: reactI18next.Interpolate,
44 | I18nextProvider: reactI18next.I18nextProvider,
45 | loadNamespaces: reactI18next.loadNamespaces,
46 | reactI18nextModule: reactI18next.reactI18nextModule,
47 | setDefaults: reactI18next.setDefaults,
48 | getDefaults: reactI18next.getDefaults,
49 | setI18n: reactI18next.setI18n,
50 | getI18n: reactI18next.getI18n,
51 | };
--------------------------------------------------------------------------------
/src/shallowEqual.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2013-present, Facebook, Inc.
3 | *
4 | * This source code is licensed under the MIT license found in the
5 | * LICENSE file in the root directory of this source tree.
6 | *
7 | * @providesModule shallowEqual
8 | * @typechecks
9 | * @flow
10 | */
11 |
12 | /* eslint-disable no-self-compare */
13 |
14 | const hasOwnProperty = Object.prototype.hasOwnProperty;
15 |
16 | /**
17 | * inlined Object.is polyfill to avoid requiring consumers ship their own
18 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
19 | */
20 | function is(x, y) {
21 | // SameValue algorithm
22 | if (x === y) {
23 | // Steps 1-5, 7-10
24 | // Steps 6.b-6.e: +0 != -0
25 | // Added the nonzero y check to make Flow happy, but it is redundant
26 | return x !== 0 || y !== 0 || 1 / x === 1 / y;
27 | }
28 | // Step 6.a: NaN == NaN
29 | return x !== x && y !== y;
30 | }
31 |
32 | /**
33 | * Performs equality by iterating through keys on an object and returning false
34 | * when any key has values which are not strictly equal between the arguments.
35 | * Returns true when the values of all keys are strictly equal.
36 | */
37 | export default function shallowEqual(objA, objB) {
38 | if (is(objA, objB)) {
39 | return true;
40 | }
41 |
42 | if (
43 | typeof objA !== 'object' ||
44 | objA === null ||
45 | typeof objB !== 'object' ||
46 | objB === null
47 | ) {
48 | return false;
49 | }
50 |
51 | const keysA = Object.keys(objA);
52 | const keysB = Object.keys(objB);
53 |
54 | if (keysA.length !== keysB.length) {
55 | return false;
56 | }
57 |
58 | // Test for A's keys different from B.
59 | for (let i = 0; i < keysA.length; i++) {
60 | if (
61 | !hasOwnProperty.call(objB, keysA[i]) ||
62 | !is(objA[keysA[i]], objB[keysA[i]])
63 | ) {
64 | return false;
65 | }
66 | }
67 |
68 | return true;
69 | }
70 |
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/i18n.js:
--------------------------------------------------------------------------------
1 | const i18n = require('i18next')
2 | const XHR = require('i18next-xhr-backend')
3 | const LanguageDetector = require('i18next-browser-languagedetector')
4 |
5 | const options = {
6 | fallbackLng: 'en',
7 | load: 'languageOnly', // we only provide en, de -> no region specific locals like en-US, de-DE
8 |
9 | // have a common namespace used around the full app
10 | ns: ['common'],
11 | defaultNS: 'common',
12 |
13 | debug: false, //process.env.NODE_ENV !== 'production',
14 | saveMissing: true,
15 |
16 | interpolation: {
17 | escapeValue: false, // not needed for react!!
18 | formatSeparator: ',',
19 | format: (value, format, lng) => {
20 | if (format === 'uppercase') return value.toUpperCase()
21 | return value
22 | }
23 | }
24 | }
25 |
26 |
27 | // for browser use xhr backend to load translations and browser lng detector
28 | if (process.browser) {
29 | i18n
30 | .use(XHR)
31 | // .use(Cache)
32 | .use(LanguageDetector)
33 | }
34 |
35 | // initialize if not already initialized
36 | if (!i18n.isInitialized) i18n.init(options)
37 |
38 | // a simple helper to getInitialProps passed on loaded i18n data
39 | i18n.getInitialProps = (req, namespaces) => {
40 | if (!namespaces) namespaces = i18n.options.defaultNS
41 | if (typeof namespaces === 'string') namespaces = [namespaces]
42 |
43 | req.i18n.toJSON = () => null // do not serialize i18next instance and send to client
44 |
45 | const initialI18nStore = {}
46 | req.i18n.languages.forEach((l) => {
47 | initialI18nStore[l] = {}
48 | namespaces.forEach((ns) => {
49 | initialI18nStore[l][ns] = (req.i18n.services.resourceStore.data[l] || {})[ns] || {}
50 | })
51 | })
52 |
53 | return {
54 | i18n: req.i18n, // use the instance on req - fixed language on request (avoid issues in race conditions with lngs of different users)
55 | initialI18nStore,
56 | initialLanguage: req.i18n.language
57 | }
58 | }
59 |
60 | module.exports = i18n;
61 |
--------------------------------------------------------------------------------
/example/nextjs-locize/i18n.js:
--------------------------------------------------------------------------------
1 | const i18n = require('i18next');
2 | const locizeBackend = require('i18next-locize-backend').default; // same as: import locizeBackend from 'i18next-locize-backend';
3 | const LanguageDetector = require('i18next-browser-languagedetector');
4 | const locizeOptions = require('./locizeOptions.json');
5 |
6 | const options = {
7 | fallbackLng: 'en',
8 | load: 'languageOnly', // we only provide en, de -> no region specific locals like en-US, de-DE
9 |
10 | // have a common namespace used around the full app
11 | ns: ['common'],
12 | defaultNS: 'common',
13 |
14 | debug: true,
15 | saveMissing: true,
16 |
17 | interpolation: {
18 | escapeValue: false, // not needed for react!!
19 | formatSeparator: ',',
20 | format: (value, format, lng) => {
21 | if (format === 'uppercase') return value.toUpperCase();
22 | return value;
23 | }
24 | },
25 | backend: locizeOptions
26 | };
27 |
28 | // for browser use xhr backend to load translations and browser lng detector
29 | if (process.browser) {
30 | i18n
31 | .use(locizeBackend)
32 | .use(LanguageDetector);
33 | }
34 |
35 | // initialize if not already initialized
36 | if (!i18n.isInitialized) i18n.init(options);
37 |
38 | // a simple helper to getInitialProps passed on loaded i18n data
39 | i18n.getInitialProps = (req, namespaces) => {
40 | if (!namespaces) namespaces = i18n.options.defaultNS;
41 | if (typeof namespaces === 'string') namespaces = [namespaces];
42 |
43 | req.i18n.toJSON = () => null; // do not serialize i18next instance and send to client
44 |
45 | const initialI18nStore = {};
46 | req.i18n.languages.forEach((l) => {
47 | initialI18nStore[l] = {};
48 | namespaces.forEach((ns) => {
49 | initialI18nStore[l][ns] = req.i18n.services.resourceStore.data[l] ? req.i18n.services.resourceStore.data[l][ns] || {} : {};
50 | });
51 | });
52 |
53 | return {
54 | i18n: req.i18n, // use the instance on req - fixed language on request (avoid issues in race conditions with lngs of different users)
55 | initialI18nStore,
56 | initialLanguage: req.i18n.language
57 | };
58 | };
59 |
60 | module.exports = i18n;
61 |
--------------------------------------------------------------------------------
/example/dat/src/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import LanguageDetector from 'i18next-browser-languagedetector';
3 | import XHR from 'i18next-xhr-backend';
4 | import LocizeBackend from 'i18next-locize-backend';
5 | import whichBackend from './whichBackend';
6 |
7 | const options = {
8 | fallbackLng: 'en',
9 |
10 | // have a common namespace used around the full app
11 | ns: ['translations'],
12 | defaultNS: 'translations',
13 |
14 | keySeparator: false, // we use content as keys
15 | nsSeparator: false, // we use content as keys
16 |
17 | interpolation: {
18 | escapeValue: false, // not needed for react!!
19 | formatSeparator: ',',
20 | },
21 |
22 | react: {
23 | wait: true,
24 | },
25 | };
26 |
27 | switch (whichBackend()) {
28 | case 'locize':
29 | options.backend = {
30 | projectId: '9fa57726-b7a6-4d1c-bbf6-37629309e4c5', // <-- replace with your projectId
31 | apiKey: 'your apiKey',
32 | referenceLng: 'en',
33 | };
34 | i18n.use(LocizeBackend);
35 | break;
36 |
37 | case 'xhr':
38 | options.backend = {
39 | loadPath: '/locales/{{lng}}/{{ns}}.json',
40 | };
41 | i18n.use(XHR);
42 | break;
43 |
44 | case 'memory':
45 | default:
46 | options.resources = {
47 | en: {
48 | translations: {
49 | 'To get started, edit <1>src/App.js1> and save to reload.': 'To get started, edit <1>src/App.js1> and save to reload.',
50 | 'Welcome to React': 'Welcome to React and react-i18next',
51 | 'advice': 'Try to set the query parameter "backend" to memory, xhr or locize i.e. {{url}}'
52 | },
53 | },
54 | de: {
55 | translations: {
56 | 'To get started, edit <1>src/App.js1> and save to reload.': 'Starte in dem du, <1>src/App.js1> editierst und speicherst.',
57 | 'Welcome to React': 'Willkommen bei React und react-i18next',
58 | 'advice': 'Versuche den query Parameter "backend" auf memory, xhr oder locize zu setzen zBsp. {{url}}'
59 | },
60 | },
61 | };
62 | }
63 |
64 | export default () => {
65 | i18n.use(LanguageDetector).init(options);
66 | return i18n;
67 | };
68 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | export default function register() {
12 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
13 | window.addEventListener('load', () => {
14 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
15 | navigator.serviceWorker
16 | .register(swUrl)
17 | .then(registration => {
18 | registration.onupdatefound = () => {
19 | const installingWorker = registration.installing;
20 | installingWorker.onstatechange = () => {
21 | if (installingWorker.state === 'installed') {
22 | if (navigator.serviceWorker.controller) {
23 | // At this point, the old content will have been purged and
24 | // the fresh content will have been added to the cache.
25 | // It's the perfect time to display a "New content is
26 | // available; please refresh." message in your web app.
27 | console.log('New content is available; please refresh.');
28 | } else {
29 | // At this point, everything has been precached.
30 | // It's the perfect time to display a
31 | // "Content is cached for offline use." message.
32 | console.log('Content is cached for offline use.');
33 | }
34 | }
35 | };
36 | };
37 | })
38 | .catch(error => {
39 | console.error('Error during service worker registration:', error);
40 | });
41 | });
42 | }
43 | }
44 |
45 | export function unregister() {
46 | if ('serviceWorker' in navigator) {
47 | navigator.serviceWorker.ready.then(registration => {
48 | registration.unregister();
49 | });
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | export default function register() {
12 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
13 | window.addEventListener('load', () => {
14 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
15 | navigator.serviceWorker
16 | .register(swUrl)
17 | .then(registration => {
18 | registration.onupdatefound = () => {
19 | const installingWorker = registration.installing;
20 | installingWorker.onstatechange = () => {
21 | if (installingWorker.state === 'installed') {
22 | if (navigator.serviceWorker.controller) {
23 | // At this point, the old content will have been purged and
24 | // the fresh content will have been added to the cache.
25 | // It's the perfect time to display a "New content is
26 | // available; please refresh." message in your web app.
27 | console.log('New content is available; please refresh.');
28 | } else {
29 | // At this point, everything has been precached.
30 | // It's the perfect time to display a
31 | // "Content is cached for offline use." message.
32 | console.log('Content is cached for offline use.');
33 | }
34 | }
35 | };
36 | };
37 | })
38 | .catch(error => {
39 | console.error('Error during service worker registration:', error);
40 | });
41 | });
42 | }
43 | }
44 |
45 | export function unregister() {
46 | if ('serviceWorker' in navigator) {
47 | navigator.serviceWorker.ready.then(registration => {
48 | registration.unregister();
49 | });
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/example/react-native-expo/js/i18n.js:
--------------------------------------------------------------------------------
1 | import i18n from 'i18next';
2 | import { reactI18nextModule } from 'react-i18next';
3 | import Expo from 'expo';
4 |
5 | // creating a language detection plugin using expo
6 | // http://i18next.com/docs/ownplugin/#languagedetector
7 | const languageDetector = {
8 | type: 'languageDetector',
9 | async: true, // flags below detection to be async
10 | detect: (callback) => { return /*'en'; */ Expo.DangerZone.Localization.getCurrentLocaleAsync().then(lng => { callback(lng.replace('_', '-')); }) },
11 | init: () => {},
12 | cacheUserLanguage: () => {}
13 | }
14 |
15 | i18n
16 | .use(languageDetector)
17 | .use(reactI18nextModule)
18 | .init({
19 | fallbackLng: 'en',
20 |
21 | resources: {
22 | en: {
23 | home: {
24 | title: 'Welcome',
25 | introduction: 'This text comes from i18next and is provided in english.'
26 | },
27 | page2: {
28 | title: 'Page 2',
29 | introduction: 'This text on page two.'
30 | },
31 | common: {
32 | currentLanguage: 'The current language is "{{lng}}"',
33 | actions: {
34 | toggleToGerman: 'Deutsch',
35 | toggleToEnglish: 'English',
36 | goToPage2: 'Open page 2'
37 | },
38 | infoText: "<0><0>Eins <1>Zwei 1><2>Drei 2><3>Vier 3><4>Fünf4>"
39 | }
40 | },
41 | de: {
42 | home: {
43 | title: 'Willkommen',
44 | introduction: 'Dieser Text ist von i18next und ist in deutsch.'
45 | },
46 | page2: {
47 | title: 'Seite 2',
48 | introduction: 'Text auf Seite 2'
49 | },
50 | common: {
51 | currentLanguage: 'Die Sprache ist auf "{{lng}}" gesetzt',
52 | actions: {
53 | toggleToGerman: 'Deutsch',
54 | toggleToEnglish: 'English',
55 | goToPage2: 'Öffne Seite 2'
56 | }
57 | }
58 | }
59 | },
60 |
61 | // have a common namespace used around the full app
62 | ns: ['common'],
63 | defaultNS: 'common',
64 |
65 | debug: true,
66 |
67 | // cache: {
68 | // enabled: true
69 | // },
70 |
71 | interpolation: {
72 | escapeValue: false, // not needed for react as it does escape per default to prevent xss!
73 | }
74 | });
75 |
76 |
77 | export default i18n;
78 |
--------------------------------------------------------------------------------
/test/icu.macro.spec.js:
--------------------------------------------------------------------------------
1 | import pluginTester from 'babel-plugin-tester';
2 | import plugin from 'babel-plugin-macros';
3 |
4 | pluginTester({
5 | plugin,
6 | snapshot: true,
7 | babelOptions: { filename: __filename, parserOpts: { plugins: ['jsx'] } },
8 | tests: [
9 | `
10 | import { Trans } from '../icu.macro'
11 |
12 | const x = Welcome, { name }!
13 | `,
14 |
15 | `
16 | import { Trans } from '../icu.macro'
17 |
18 | const x = Welcome, { name } !
19 | `,
20 |
21 | `
22 | import { Trans } from '../icu.macro'
23 |
24 | const x = Trainers: { trainersCount, number }
25 | `,
26 |
27 | `
28 | import { Trans } from '../icu.macro'
29 |
30 | const x = Trainers: { trainersCount, number } !
31 | `,
32 |
33 | `
34 | import { Trans } from '../icu.macro'
35 |
36 | const x = Caught on { catchDate, date, short }
37 | `,
38 |
39 | `
40 | import { Trans } from '../icu.macro'
41 |
42 | const x = Caught on { catchDate, date, short } !
43 | `,
44 |
45 | `
46 | import { Select } from '../icu.macro'
47 |
48 | const x =
54 | `,
55 |
56 | `
57 | import { Select } from '../icu.macro'
58 |
59 | const x = He avoids bugs.}
62 | female={She avoids bugs. }
63 | other={They avoid bugs. }
64 | />
65 | `,
66 |
67 | `
68 | import { Plural } from '../icu.macro'
69 |
70 | const x =
76 | `,
77 |
78 | `
79 | import { Plural } from '../icu.macro'
80 |
81 | const x = There is no item.}
85 | one={There is # item. }
86 | other={There are # items. }
87 | />
88 | `,
89 | ],
90 | });
91 |
--------------------------------------------------------------------------------
/example/react-native-expo/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | ; We fork some components by platform
3 | .*/*[.]android.js
4 |
5 | ; Ignore templates for 'react-native init'
6 | /node_modules/react-native/local-cli/templates/.*
7 |
8 | ; Ignore RN jest
9 | /node_modules/react-native/jest/.*
10 |
11 | ; Ignore RNTester
12 | /node_modules/react-native/RNTester/.*
13 |
14 | ; Ignore the website subdir
15 | /node_modules/react-native/website/.*
16 |
17 | ; Ignore the Dangerfile
18 | /node_modules/react-native/danger/dangerfile.js
19 |
20 | ; Ignore Fbemitter
21 | /node_modules/fbemitter/.*
22 |
23 | ; Ignore "BUCK" generated dirs
24 | /node_modules/react-native/\.buckd/
25 |
26 | ; Ignore unexpected extra "@providesModule"
27 | .*/node_modules/.*/node_modules/fbjs/.*
28 |
29 | ; Ignore polyfills
30 | /node_modules/react-native/Libraries/polyfills/.*
31 |
32 | ; Ignore various node_modules
33 | /node_modules/react-native-gesture-handler/.*
34 | /node_modules/expo/.*
35 | /node_modules/react-navigation/.*
36 | /node_modules/xdl/.*
37 | /node_modules/reqwest/.*
38 | /node_modules/metro-bundler/.*
39 |
40 | [include]
41 |
42 | [libs]
43 | node_modules/react-native/Libraries/react-native/react-native-interface.js
44 | node_modules/react-native/flow/
45 | node_modules/expo/flow/
46 |
47 | [options]
48 | emoji=true
49 |
50 | module.system=haste
51 |
52 | module.file_ext=.js
53 | module.file_ext=.jsx
54 | module.file_ext=.json
55 | module.file_ext=.ios.js
56 |
57 | munge_underscores=true
58 |
59 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
60 |
61 | suppress_type=$FlowIssue
62 | suppress_type=$FlowFixMe
63 | suppress_type=$FlowFixMeProps
64 | suppress_type=$FlowFixMeState
65 | suppress_type=$FixMe
66 |
67 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(5[0-6]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)
68 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(5[0-6]\\|[1-4][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native_oss[a-z,_]*\\)?)\\)?:? #[0-9]+
69 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
70 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
71 |
72 | unsafe.enable_getters_and_setters=true
73 |
74 | [version]
75 | ^0.56.0
76 |
--------------------------------------------------------------------------------
/example/dat/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/react_withHOC/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/storybook/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/test-jest/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/locize-example/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/preact_renderProps/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/preact_withHOC/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/react_renderProps/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/react_fluent_withHOC/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["airbnb", "prettier", "prettier/react"],
3 | "parser": "babel-eslint",
4 | "parserOptions": {
5 | "ecmaVersion": 8,
6 | "ecmaFeatures": {
7 | "experimentalObjectRestSpread": true,
8 | "impliedStrict": true,
9 | "classes": true
10 | }
11 | },
12 | "env": {
13 | "browser": true,
14 | "node": true,
15 | "jquery": true,
16 | "jest": true
17 | },
18 | "rules": {
19 | "no-debugger": 0,
20 | "no-alert": 0,
21 | "no-unused-vars": [
22 | 1,
23 | {
24 | "argsIgnorePattern": "res|next|^err"
25 | }
26 | ],
27 | "prefer-const": [
28 | "error",
29 | {
30 | "destructuring": "all"
31 | }
32 | ],
33 | "arrow-body-style": [2, "as-needed"],
34 | "no-unused-expressions": [
35 | 2,
36 | {
37 | "allowTaggedTemplates": true
38 | }
39 | ],
40 | "no-param-reassign": [
41 | 2,
42 | {
43 | "props": false
44 | }
45 | ],
46 | "no-console": 0,
47 | "no-use-before-define": 0,
48 | "no-nested-ternary": 0,
49 | "import/prefer-default-export": 0,
50 | "import/no-extraneous-dependencies": 1,
51 | "import/no-named-as-default-member": 1,
52 | "import": 0,
53 | "func-names": 0,
54 | "space-before-function-paren": 0,
55 | "comma-dangle": 0,
56 | "max-len": 0,
57 | "import/extensions": 0,
58 | "no-underscore-dangle": 0,
59 | "consistent-return": 0,
60 | "react/display-name": 1,
61 | "react/no-array-index-key": 0,
62 | "react/react-in-jsx-scope": 0,
63 | "react/prefer-stateless-function": 0,
64 | "react/forbid-prop-types": 0,
65 | "react/no-unescaped-entities": 0,
66 | "react/prop-types": 0,
67 | "jsx-a11y/accessible-emoji": 0,
68 | "react/jsx-filename-extension": [
69 | 1,
70 | {
71 | "extensions": [".js", ".jsx"]
72 | }
73 | ],
74 | "radix": 0,
75 | "no-shadow": [
76 | 2,
77 | {
78 | "hoist": "all",
79 | "allow": ["resolve", "reject", "done", "next", "err", "error"]
80 | }
81 | ],
82 | "quotes": [
83 | 2,
84 | "single",
85 | {
86 | "avoidEscape": true,
87 | "allowTemplateLiterals": true
88 | }
89 | ],
90 | "prettier/prettier": [
91 | "error",
92 | {
93 | "trailingComma": "es5",
94 | "singleQuote": true,
95 | "printWidth": 100
96 | }
97 | ],
98 | "jsx-a11y/href-no-hash": "off",
99 | "jsx-a11y/anchor-is-valid": [
100 | "warn",
101 | {
102 | "aspects": ["invalidHref"]
103 | }
104 | ]
105 | },
106 | "plugins": ["prettier"]
107 | }
108 |
--------------------------------------------------------------------------------
/example/nextjs-locize/README.md:
--------------------------------------------------------------------------------
1 | [](https://youtu.be/kw-GEQbgmSc)
2 |
3 | [watch the video](https://youtu.be/kw-GEQbgmSc)
4 |
5 | [relevant changes](https://github.com/i18next/react-i18next/commit/b5cd5c07f73d52d306fae4833203d9adc7edd839)
6 |
7 | # Getting started
8 |
9 | Build with [next.js](https://github.com/zeit/next.js/).
10 |
11 | ```bash
12 | # npm install
13 | # npm run dev
14 | ```
15 |
16 | **open:**
17 |
18 | auto detecting user language: [http://localhost:3000](http://localhost:3000)
19 |
20 | german: [http://localhost:3000/?lng=de](http://localhost:3000/?lng=de)
21 |
22 | english: [http://localhost:3000/?lng=en](http://localhost:3000/?lng=en)
23 |
24 |
25 | ## The idea behind the example
26 |
27 | This example app shows how to integrate [react-i18next](https://github.com/i18next/react-i18next) with [Next](https://github.com/zeit/next.js) and locize backend.
28 |
29 | ## using with locize
30 |
31 | We added our translation management [locize.com](http://locize.com).
32 |
33 | - [i18next-locize-backend](https://github.com/locize/i18next-locize-backend)
34 | - [i18next-node-locize-backend](https://github.com/locize/i18next-node-locize-backend)
35 |
36 | You will find your project informations like projectId and apiKey on your locize projects settings. (Signup add a new project for testing).
37 |
38 | Set projectId and apiKey in `/locize.json`.
39 |
40 | **Plus:**
41 |
42 | - Routing and separating translations into multiple files (lazy load them on client routing)
43 | - Child components (pure or using translation hoc)
44 |
45 | ### Features of this example app
46 |
47 | - Server-side language negotiation
48 | - Full control and usage of i18next on express server using [i18next-express-middleware](https://github.com/i18next/i18next-express-middleware) which asserts no async request collisions resulting in wrong language renderings
49 | - Support for save missing features to get untranslated keys automatically created `locales/{lng}/{namespace}.missing.json` -> never miss to translate a key
50 | - Proper pass down on translations via initialProps
51 | - Taking advantage of multiple translation files including lazy loading on client (no need to load all translations upfront)
52 | - Use express to also serve translations for clientside
53 | - In contrast to react-intl the translations are visible both during development and in production
54 |
55 | ### learn more
56 |
57 | - [next.js](https://github.com/zeit/next.js)
58 | - [react-i18next repository](https://github.com/i18next/react-i18next)
59 | - [react-i18next documentation](https://react.i18next.com)
60 |
61 | **Translation features:**
62 |
63 | - [i18next repository](https://github.com/i18next/i18next)
64 | - [i18next documentation](https://www.i18next.com)
65 |
66 | **Translation management:**
67 |
68 | - [locize](http://locize.com)
69 |
--------------------------------------------------------------------------------
/test/i18nextProvider.spec.js:
--------------------------------------------------------------------------------
1 | jest.unmock('../src/I18nextProvider');
2 | import React from 'react';
3 | import PropTypes from 'prop-types';
4 | import I18nextProvider from '../src/I18nextProvider';
5 |
6 | describe('I18nextProvider', () => {
7 | it('should provide i18n context', () => {
8 | const i18n = {
9 | options: {},
10 | services: {
11 | resourceStore: {
12 | data: {}
13 | }
14 | },
15 | changeLanguage: () => {}
16 | };
17 | const wrapper = new I18nextProvider({ i18n, initialI18nStore: {}, initialLanguage: 'en' });
18 | expect(wrapper.getChildContext().i18n).toBe(i18n);
19 | expect(I18nextProvider.childContextTypes.i18n)
20 | .toBe(PropTypes.object.isRequired);
21 | });
22 | it('should throw an exception if you try to change i18n object', () => {
23 | const i18n = {};
24 | const wrapper = new I18nextProvider({ i18n });
25 | wrapper.props.i18n = { anoter: true };
26 | function willReceiveProps() {
27 | wrapper.componentWillReceiveProps({ i18n: {} });
28 | }
29 | expect(willReceiveProps).toThrowError('[react-i18next][I18nextProvider]does not support changing the i18n object.');
30 | });
31 | it('should render children', () => {
32 | const div = React.createFactory('div');
33 | const child = React.createElement(div);
34 | const wrapper = new I18nextProvider({ i18n: {}, children: child });
35 | const render = wrapper.render();
36 | expect(render).toBe(child);
37 | });
38 | it('should provide defaultNS', () => {
39 | const i18n = {
40 | options: {},
41 | services: {
42 | resourceStore: {
43 | data: {}
44 | }
45 | },
46 | changeLanguage: () => {}
47 | };
48 | const wrapper = new I18nextProvider({ i18n, defaultNS: 'provided-namespace', initialI18nStore: {}, initialLanguage: 'en' });
49 | expect(wrapper.getChildContext().defaultNS).toBe('provided-namespace');
50 | expect(I18nextProvider.childContextTypes.defaultNS)
51 | .toBe(PropTypes.string);
52 | });
53 | it('should provide reportNS', () => {
54 | const i18n = {
55 | options: {},
56 | services: {
57 | resourceStore: {
58 | data: {}
59 | }
60 | },
61 | changeLanguage: () => {}
62 | };
63 | const wrapper = new I18nextProvider({ i18n, defaultNS: '', initialI18nStore: {}, initialLanguage: 'en', reportNS: (ns) => ns });
64 | expect(wrapper.getChildContext().reportNS('_ns_')).toBe('_ns_');
65 | expect(I18nextProvider.childContextTypes.reportNS)
66 | .toBe(PropTypes.func);
67 | });
68 | it('should have i18n proptype required', () => {
69 | expect(I18nextProvider.propTypes.i18n)
70 | .toBe(PropTypes.object.isRequired);
71 | });
72 | it('should have defaultNS proptype optional string', () => {
73 | expect(I18nextProvider.propTypes.defaultNS)
74 | .toBe(PropTypes.string);
75 | });
76 | it('should have children proptype required', () => {
77 | expect(I18nextProvider.propTypes.children)
78 | .toBe(PropTypes.element.isRequired);
79 | });
80 | });
81 |
--------------------------------------------------------------------------------
/example/react_icu_withHOC/src/ComponentUsingMacro.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { translate } from 'react-i18next';
3 |
4 | // importing the macro components from react-i18next
5 | import { Trans, Plural, Select } from 'react-i18next/icu.macro';
6 |
7 | // as we "bend" some es-lint rules we need to disable those
8 | // this let us write "{ trainersCount, number }" or "{ catchDate, date, short }"
9 | // inside Trans -> other option would be an additional component which transforms
10 | // to needed string, eg.
11 | /* eslint-disable no-undef, no-sequences */
12 | export function ComponentUsingMacro() {
13 | const name = 'John Doe';
14 | const itemsCount1 = 0;
15 | const itemsCount2 = 1;
16 | const itemsCount3 = 199;
17 | const trainersCount = 134567;
18 |
19 | const catchDate = new Date();
20 | const gender = 'female';
21 |
22 |
23 | return (
24 |
25 |
26 |
Using babel macro plugin to transpile icu containing nodes into valid Trans component:
27 |
28 |
29 |
interpolation:
30 |
Welcome, { name }!
31 |
32 |
Welcome, { name } !
33 |
34 |
Trainers: { trainersCount, number }
35 |
36 |
Trainers: { trainersCount, number } !
37 |
38 |
Caught on { catchDate, date, short }
39 |
40 |
Caught on { catchDate, date, short } !
41 |
42 |
select:
43 |
49 |
50 |
He avoids bugs.}
53 | female={She avoids bugs. }
54 | other={They avoid bugs. }
55 | />
56 |
57 | plurals:
58 |
64 |
65 |
71 |
72 |
78 |
79 | There is no item.}
83 | one={There is # item. }
84 | other={There are # items. }
85 | />
86 |
87 | );
88 | }
89 | /* eslint-enable no-undef, no-sequences */
90 |
91 | export default translate('translations')(ComponentUsingMacro);
--------------------------------------------------------------------------------
/example/nextjs_withAppJS/README.md:
--------------------------------------------------------------------------------
1 | [](https://deploy.now.sh/?repo=https://github.com/zeit/next.js/tree/master/examples/with-react-i18next)
2 |
3 | # Internationalization with [react-i18next](https://github.com/i18next/react-i18next).
4 |
5 | ## How to use
6 |
7 | ### Using `create-next-app`
8 |
9 | Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
10 |
11 | ```bash
12 | npx create-next-app --example with-react-i18next with-react-i18next-app
13 | # or
14 | yarn create next-app --example with-react-i18next with-react-i18next-app
15 | ```
16 |
17 | ### Download manually
18 |
19 | Download the example [or clone the repo](https://github.com/zeit/next.js):
20 |
21 | ```bash
22 | curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-react-i18next
23 | cd with-react-i18next
24 | ```
25 |
26 | Install it and run:
27 |
28 | ```bash
29 | npm install
30 | npm run dev
31 | # or
32 | yarn
33 | yarn dev
34 | ```
35 |
36 | Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
37 |
38 | ```bash
39 | now
40 | ```
41 |
42 | ### Testing the app
43 |
44 | auto detecting user language: [http://localhost:3000](http://localhost:3000)
45 |
46 | german: [http://localhost:3000/?lng=de](http://localhost:3000/?lng=de)
47 |
48 | english: [http://localhost:3000/?lng=en](http://localhost:3000/?lng=en)
49 |
50 | ## The idea behind the example
51 |
52 | This example app shows how to integrate [react-i18next](https://github.com/i18next/react-i18next) with [Next](https://github.com/zeit/next.js).
53 |
54 | **Plus:**
55 |
56 | * Routing and separating translations into multiple files (lazy load them on client routing)
57 | * Child components (pure or using translation hoc)
58 |
59 | ### Features of this example app
60 |
61 | * Server-side language negotiation
62 | * Full control and usage of i18next on express server using [i18next-express-middleware](https://github.com/i18next/i18next-express-middleware) which asserts no async request collisions resulting in wrong language renderings
63 | * Support for save missing features to get untranslated keys automatically created `locales/{lng}/{namespace}.missing.json` -> never miss to translate a key
64 | * Proper pass down on translations via initialProps
65 | * Taking advantage of multiple translation files including lazy loading on client (no need to load all translations upfront)
66 | * Use express to also serve translations for clientside
67 | * In contrast to react-intl the translations are visible both during development and in production
68 |
69 | ### learn more
70 |
71 | * [next.js](https://github.com/zeit/next.js)
72 | * [react-i18next repository](https://github.com/i18next/react-i18next)
73 | * [react-i18next documentation](https://react.i18next.com)
74 |
75 | **Translation features:**
76 |
77 | * [i18next repository](https://github.com/i18next/i18next)
78 | * [i18next documentation](https://www.i18next.com)
79 |
80 | **Translation management:**
81 |
82 | * [locize](http://locize.com)
83 |
--------------------------------------------------------------------------------
/example/razzle-ssr/src/server.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-dynamic-require */
2 | import React from 'react';
3 | import { StaticRouter, matchPath } from 'react-router-dom';
4 |
5 | import express from 'express';
6 | import path from 'path';
7 | import fs from 'fs';
8 | import { renderToString } from 'react-dom/server';
9 |
10 | import { I18nextProvider } from 'react-i18next'; // has no proper import yet
11 | import Backend from 'i18next-node-fs-backend';
12 | import App from './App';
13 | import i18n from './i18n';
14 |
15 | // Make sure any symlinks in the project folder are resolved:
16 | // https://github.com/facebookincubator/create-react-app/issues/637
17 | const appDirectory = fs.realpathSync(process.cwd());
18 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
19 | const appSrc = resolveApp('src');
20 |
21 | const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);
22 | const i18nextMiddleware = require('i18next-express-middleware');
23 |
24 | const server = express();
25 |
26 | i18n
27 | .use(Backend)
28 | .use(i18nextMiddleware.LanguageDetector)
29 | .init(
30 | {
31 | preload: ['en', 'de'],
32 | backend: {
33 | loadPath: `${appSrc}/locales/{{lng}}/{{ns}}.json`,
34 | addPath: `${appSrc}/locales/{{lng}}/{{ns}}.missing.json`,
35 | },
36 | },
37 | () => {
38 | server
39 | .disable('x-powered-by')
40 | .use(i18nextMiddleware.handle(i18n))
41 | .use('/locales', express.static(`${appSrc}/locales`))
42 | .use(express.static(process.env.RAZZLE_PUBLIC_DIR))
43 | .get('/*', (req, res) => {
44 | const context = {};
45 | const markup = renderToString(
46 |
47 |
48 |
49 |
50 |
51 | );
52 | // This line must be placed after renderToString method
53 | // otherwise context won't be populated by App
54 | const { url } = context;
55 | if (url) {
56 | res.redirect(url);
57 | } else {
58 | const initialI18nStore = {};
59 | req.i18n.languages.forEach(l => {
60 | console.log(req.i18n.services.resourceStore.data[l]);
61 | initialI18nStore[l] = req.i18n.services.resourceStore.data[l];
62 | });
63 | debugger;
64 | const initialLanguage = req.i18n.language;
65 |
66 | res.status(200).send(
67 | `
68 |
69 |
70 |
71 |
72 | Welcome to Razzle
73 |
74 | ${assets.client.css ? ` ` : ''}
75 |
76 |
80 |
81 |
82 | ${markup}
83 |
84 | `
85 | );
86 | }
87 | });
88 | }
89 | );
90 |
91 | export default server;
92 |
--------------------------------------------------------------------------------