1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00
next.js/examples/with-react-i18next
Zack Tanner 9854c342e1 #5620: Fix react-i18next example to properly SSR (#5265)
This fixes https://github.com/zeit/next.js/issues/5260 by making sure that `index.js` has `getInitialProps` defined on the page exported component, not the child component.

When fixing that, I uncovered an issue where the server side rendered HTML did not match the clientside HTML, so I reworked _app.js to use the `i18nextprovider` component which has props to hydrate the initial data (for SSR), and makes sure the correct i18n instance is passed to all child components through context.

Before:
```html
<!DOCTYPE html>
<html>
   <head>
      <meta charSet="utf-8" class="next-head"/>
      <link rel="preload" href="/_next/static/development/pages/index.js" as="script"/>
      <link rel="preload" href="/_next/static/development/pages/_app.js" as="script"/>
      <link rel="preload" href="/_next/static/development/pages/_error.js" as="script"/>
      <link rel="preload" href="/_next/static/runtime/webpack.js" as="script"/>
      <link rel="preload" href="/_next/static/runtime/main.js" as="script"/>
   </head>
   <body>
      <div id="__next"></div>
      <script src="/_next/static/development/dll/dll_4a2ab6ce0cb456fbfead.js"></script><script>__NEXT_DATA__ = {"props":{"pageProps":{}},"page":"/","pathname":"/","query":{},"buildId":"development"};__NEXT_LOADED_PAGES__=[];__NEXT_REGISTER_PAGE=function(r,f){__NEXT_LOADED_PAGES__.push([r, f])}</script><script async="" id="__NEXT_PAGE__/" src="/_next/static/development/pages/index.js"></script><script async="" id="__NEXT_PAGE__/_app" src="/_next/static/development/pages/_app.js"></script><script async="" id="__NEXT_PAGE__/_error" src="/_next/static/development/pages/_error.js"></script><script src="/_next/static/runtime/webpack.js" async=""></script><script src="/_next/static/runtime/main.js" async=""></script>
   </body>
</html>
```

After: 
```html
<!DOCTYPE html>
<html>
   <head>
      <meta charSet="utf-8" class="next-head"/>
      <link rel="preload" href="/_next/static/development/pages/index.js" as="script"/>
      <link rel="preload" href="/_next/static/development/pages/_app.js" as="script"/>
      <link rel="preload" href="/_next/static/development/pages/_error.js" as="script"/>
      <link rel="preload" href="/_next/static/runtime/webpack.js" as="script"/>
      <link rel="preload" href="/_next/static/runtime/main.js" as="script"/>
   </head>
   <body>
      <div id="__next">
         <h1>This example integrates react-i18next for simple internationalization.</h1>
         <div>
            <h1>welcome to next.js</h1>
            <p>This example integrates react-i18next for simple internationalization.</p>
            <p>test words for en</p>
            <div><button>fire in the wind for en</button></div>
            <p>You can either pass t function to child components.</p>
            <p>Or wrap your component using the translate hoc provided by react-i18next.</p>
            <p>Alternatively, you can use <code>Trans</code> component.</p>
            <a href="/page2">Go to page 2</a><br/><a href="/page3">Go to page 3 (no hoc)</a>
         </div>
      </div>
      <script src="/_next/static/development/dll/dll_4a2ab6ce0cb456fbfead.js"></script><script>__NEXT_DATA__ = {"props":{"pageProps":{"i18n":null,"initialI18nStore":{"en":{"home":{"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","gotoPage3":"Go to page 3 (no hoc)"}},"common":{"integrates_react-i18next":"This example integrates react-i18next for simple internationalization.","pureComponent":"You can either pass t function to child components.","extendedComponent":"Or wrap your component using the translate hoc provided by react-i18next.","transComponent":"Alternatively, you can use \u003c1\u003eTrans\u003c/1\u003e component."}}},"initialLanguage":"en-US"}},"page":"/","pathname":"/","query":{},"buildId":"development"};__NEXT_LOADED_PAGES__=[];__NEXT_REGISTER_PAGE=function(r,f){__NEXT_LOADED_PAGES__.push([r, f])}</script><script async="" id="__NEXT_PAGE__/" src="/_next/static/development/pages/index.js"></script><script async="" id="__NEXT_PAGE__/_app" src="/_next/static/development/pages/_app.js"></script><script async="" id="__NEXT_PAGE__/_error" src="/_next/static/development/pages/_error.js"></script><script src="/_next/static/runtime/webpack.js" async=""></script><script src="/_next/static/runtime/main.js" async=""></script>
   </body>
</html>
```
2018-09-24 12:13:38 +02:00
..
components Update with-react-i18next example (#3932) 2018-03-05 12:46:13 +01:00
lib #5620: Fix react-i18next example to properly SSR (#5265) 2018-09-24 12:13:38 +02:00
locales Update with react 18next to latest (#5017) 2018-08-24 09:49:10 +02:00
pages #5620: Fix react-i18next example to properly SSR (#5265) 2018-09-24 12:13:38 +02:00
i18n.js Update with react 18next to latest (#5017) 2018-08-24 09:49:10 +02:00
package.json Update with react 18next to latest (#5017) 2018-08-24 09:49:10 +02:00
README.md Update with react 18next to latest (#5017) 2018-08-24 09:49:10 +02:00
server.js Update with react 18next to latest (#5017) 2018-08-24 09:49:10 +02:00

Deploy to now

Internationalization with react-i18next.

How to use

Using create-next-app

Execute create-next-app with Yarn or npx to bootstrap the example:

npx create-next-app --example with-react-i18next with-react-i18next-app
# or
yarn create next-app --example with-react-i18next with-react-i18next-app

Download manually

Download the example:

curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-react-i18next
cd with-react-i18next

Install it and run:

npm install
npm run dev
# or
yarn
yarn dev

Deploy it to the cloud with now (download)

now

Testing the app

auto detecting user language: http://localhost:3000

german: http://localhost:3000/?lng=de

english: http://localhost:3000/?lng=en

The idea behind the example

This example app shows how to integrate react-i18next with Next.

Plus:

  • 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 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

Translation features:

Translation management: