Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update with react 18next to latest #5017

Merged
merged 3 commits into from
Aug 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions examples/with-react-i18next/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,30 +53,30 @@ This example app shows how to integrate [react-i18next](https://github.com/i18ne

**Plus:**

* Routing and separating translations into multiple files (lazy load them on client routing)
* Child components (pure or using translation hoc)
- Routing and separating translations into multiple files (lazy load them on client routing)
- Child components (pure or using translation hoc)

### Features of this example app

* Server-side language negotiation
* 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
* Support for save missing features to get untranslated keys automatically created `locales/{lng}/{namespace}.missing.json` -> never miss to translate a key
* Proper pass down on translations via initialProps
* Taking advantage of multiple translation files including lazy loading on client (no need to load all translations upfront)
* Use express to also serve translations for clientside
* In contrast to react-intl the translations are visible both during development and in production
- Server-side language negotiation
- 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
- Support for save missing features to get untranslated keys automatically created `locales/{lng}/{namespace}.missing.json` -> never miss to translate a key
- Proper pass down on translations via initialProps
- Taking advantage of multiple translation files including lazy loading on client (no need to load all translations upfront)
- Use express to also serve translations for clientside
- In contrast to react-intl the translations are visible both during development and in production

### learn more

* [next.js](https://github.com/zeit/next.js)
* [react-i18next repository](https://github.com/i18next/react-i18next)
* [react-i18next documentation](https://react.i18next.com)
- [next.js](https://github.com/zeit/next.js)
- [react-i18next repository](https://github.com/i18next/react-i18next)
- [react-i18next documentation](https://react.i18next.com)

**Translation features:**

* [i18next repository](https://github.com/i18next/i18next)
* [i18next documentation](https://www.i18next.com)
- [i18next repository](https://github.com/i18next/i18next)
- [i18next documentation](https://www.i18next.com)

**Translation management:**

* [locize](http://locize.com)
- [locize](http://locize.com)
20 changes: 7 additions & 13 deletions examples/with-react-i18next/i18n.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const i18next = require('i18next')
const i18n = require('i18next')
const XHR = require('i18next-xhr-backend')
const LanguageDetector = require('i18next-browser-languagedetector')

Expand All @@ -10,7 +10,7 @@ const options = {
ns: ['common'],
defaultNS: 'common',

debug: process.env.NODE_ENV !== 'production',
debug: false, // process.env.NODE_ENV !== 'production',
saveMissing: true,

interpolation: {
Expand All @@ -23,22 +23,20 @@ const options = {
}
}

const i18nInstance = i18next

// for browser use xhr backend to load translations and browser lng detector
if (process.browser) {
i18nInstance
i18n
.use(XHR)
// .use(Cache)
.use(LanguageDetector)
}

// initialize if not already initialized
if (!i18nInstance.isInitialized) i18nInstance.init(options)
if (!i18n.isInitialized) i18n.init(options)

// a simple helper to getInitialProps passed on loaded i18n data
const getInitialProps = (req, namespaces) => {
if (!namespaces) namespaces = i18nInstance.options.defaultNS
i18n.getInitialProps = (req, namespaces) => {
if (!namespaces) namespaces = i18n.options.defaultNS
if (typeof namespaces === 'string') namespaces = [namespaces]

req.i18n.toJSON = () => null // do not serialize i18next instance and send to client
Expand All @@ -58,8 +56,4 @@ const getInitialProps = (req, namespaces) => {
}
}

module.exports = {
getInitialProps,
i18nInstance,
I18n: i18next.default
}
module.exports = i18n
13 changes: 5 additions & 8 deletions examples/with-react-i18next/lib/withI18next.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { translate, loadNamespaces } from 'react-i18next'
import { getInitialProps, I18n } from '../i18n'
import { translate } from 'react-i18next'
import i18n from '../i18n'

export const withI18next = (namespaces = ['common']) => ComposedComponent => {
const Extended = translate(namespaces, { i18n: I18n, wait: process.browser })(
const Extended = translate(namespaces, { i18n, wait: process.browser })(
ComposedComponent
)

Expand All @@ -12,11 +12,8 @@ export const withI18next = (namespaces = ['common']) => ComposedComponent => {
: {}

const i18nInitialProps = ctx.req
? getInitialProps(ctx.req, namespaces)
: await loadNamespaces({
components: [{ props: { namespaces } }],
i18n: I18n
})
? i18n.getInitialProps(ctx.req, namespaces)
: {}

return {
...composedInitialProps,
Expand Down
5 changes: 4 additions & 1 deletion examples/with-react-i18next/locales/de/home.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"welcome": "Willkommen zu next.js",
"sample_test": "test words for de",
"sample_button": "fire in the wind for de",
"link": {
"gotoPage2": "Zur Seite 2"
"gotoPage2": "Zur Seite 2",
"gotoPage3": "Zur Seite 3 (no hoc)"
}
}
5 changes: 4 additions & 1 deletion examples/with-react-i18next/locales/en/home.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"welcome": "welcome to next.js",
"sample_test": "test words for en",
"sample_button": "fire in the wind for en",
"link": {
"gotoPage2": "Go to page 2"
"gotoPage2": "Go to page 2",
"gotoPage3": "Go to page 3 (no hoc)"
}
}
18 changes: 9 additions & 9 deletions examples/with-react-i18next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
"author": "",
"license": "MIT",
"dependencies": {
"express": "4.16.2",
"i18next": "10.4.1",
"i18next-browser-languagedetector": "2.1.0",
"i18next-express-middleware": "1.0.10",
"i18next-node-fs-backend": "1.0.0",
"express": "4.16.3",
"i18next": "11.3.6",
"i18next-browser-languagedetector": "2.2.0",
"i18next-express-middleware": "1.2.0",
"i18next-node-fs-backend": "1.2.1",
"i18next-xhr-backend": "1.5.1",
"next": "5.0.0",
"react": "16.2.0",
"react-dom": "16.2.0",
"react-i18next": "7.3.6"
"next": "^6.1.1",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-i18next": "7.8.1"
}
}
24 changes: 24 additions & 0 deletions examples/with-react-i18next/pages/_app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import App, { Container } from 'next/app'
import { I18n as I18nR } from 'react-i18next'
import i18n from '../i18n'

export default class MyApp extends App {
render () {
const { Component, pageProps } = this.props

return (
<Container>
<I18nR ns='common' i18n={(pageProps && pageProps.i18n) || i18n} wait>
{
(t) => (
<div>
<h1>{t('common:integrates_react-i18next')}</h1>
<Component {...pageProps} />
</div>
)
}
</I18nR>
</Container>
)
}
}
16 changes: 15 additions & 1 deletion examples/with-react-i18next/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,29 @@ import ExtendedComponent from '../components/ExtendedComponent'
import ComponentWithTrans from '../components/ComponentWithTrans'
import { withI18next } from '../lib/withI18next'

export default withI18next(['home', 'common'])(({ t, initialI18nStore }) => (
const TestContent = withI18next(['home', 'common'])(({ t, initialI18nStore }) => (
<div>
<h1>{t('welcome')}</h1>
<p>{t('common:integrates_react-i18next')}</p>
<p>{t('sample_test')}</p>
<div>
<button>{t('sample_button')}</button>
</div>
<PureComponent t={t} />
<ExtendedComponent />
<ComponentWithTrans />
<Link href='/page2'>
<a>{t('link.gotoPage2')}</a>
</Link>
<br />
<Link href='/page3'>
<a>{t('link.gotoPage3')}</a>
</Link>
</div>
))

const Test = () => {
return <TestContent />
}

export default Test
6 changes: 4 additions & 2 deletions examples/with-react-i18next/pages/page2.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ExtendedComponent from '../components/ExtendedComponent'
import ComponentWithTrans from '../components/ComponentWithTrans'
import { withI18next } from '../lib/withI18next'

export default withI18next(['page2', 'common'])(({ t, initialI18nStore }) => (
const Page2 = ({ t }) => (
<div>
<h1>{t('welcomePage2')}</h1>
<p>{t('common:integrates_react-i18next')}</p>
Expand All @@ -17,4 +17,6 @@ export default withI18next(['page2', 'common'])(({ t, initialI18nStore }) => (
<a>{t('link.gotoPage1')}</a>
</Link>
</div>
))
)

export default withI18next(['page2', 'common'])(Page2)
14 changes: 14 additions & 0 deletions examples/with-react-i18next/pages/page3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// a page not using i18next - no hoc - not t function
import React from 'react'
import Link from 'next/link'

export default () => {
return (
<div>
<h1>Hello Page 3</h1>
<Link href='/'>
<a>back</a>
</Link>
</div>
)
}
8 changes: 4 additions & 4 deletions examples/with-react-i18next/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ const handle = app.getRequestHandler()

const i18nextMiddleware = require('i18next-express-middleware')
const Backend = require('i18next-node-fs-backend')
const { i18nInstance } = require('./i18n')
const i18n = require('./i18n')

// init i18next with serverside settings
// using i18next-express-middleware
i18nInstance
i18n
.use(Backend)
.use(i18nextMiddleware.LanguageDetector)
.init({
Expand All @@ -30,13 +30,13 @@ i18nInstance
const server = express()

// enable middleware for i18next
server.use(i18nextMiddleware.handle(i18nInstance))
server.use(i18nextMiddleware.handle(i18n))

// serve locales for client
server.use('/locales', express.static(path.join(__dirname, '/locales')))

// missing keys
server.post('/locales/add/:lng/:ns', i18nextMiddleware.missingKeyHandler(i18nInstance))
server.post('/locales/add/:lng/:ns', i18nextMiddleware.missingKeyHandler(i18n))

// use next.js
server.get('*', (req, res) => handle(req, res))
Expand Down