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

Internationalization with react-i18next -> translations are not displayed server side #5260

Closed
nagman opened this issue Sep 23, 2018 · 1 comment · Fixed by #5265
Closed
Labels
good first issue Easy to fix issues, good for newcomers

Comments

@nagman
Copy link

nagman commented Sep 23, 2018

translations are not displayed server side

Internationalization with react-i18next

Describe the bug

When you run the example and look at the source code of the page, you got:

<!DOCTYPE html><html><head><meta charSet="utf-8" class="next-head"/><link rel="preload" href="/_next/-/page/index.js" as="script"/><link rel="preload" href="/_next/-/page/_app.js" as="script"/><link rel="preload" href="/_next/-/page/_error.js" as="script"/><link rel="preload" href="/_next/static/commons/manifest.js" as="script"/><link rel="preload" href="/_next/static/commons/main.js" as="script"/></head><body><div id="__next"></div><div id="__next-error"></div><script>
          __NEXT_DATA__ = {"props":{"pageProps":{}},"page":"/","pathname":"/","query":{},"buildId":"-","assetPrefix":"","nextExport":false,"err":null,"chunks":[]}
          module={}
          __NEXT_LOADED_PAGES__ = []
          __NEXT_LOADED_CHUNKS__ = []

          __NEXT_REGISTER_PAGE = function (route, fn) {
            __NEXT_LOADED_PAGES__.push({ route: route, fn: fn })
          }

          __NEXT_REGISTER_CHUNK = function (chunkName, fn) {
            __NEXT_LOADED_CHUNKS__.push({ chunkName: chunkName, fn: fn })
          }

          false
        </script><script async="" id="__NEXT_PAGE__/" src="/_next/-/page/index.js"></script><script async="" id="__NEXT_PAGE__/_app" src="/_next/-/page/_app.js"></script><script async="" id="__NEXT_PAGE__/_error" src="/_next/-/page/_error.js"></script><script src="/_next/static/commons/manifest.js"></script><script src="/_next/static/commons/main.js"></script></body></html>

As you can see, there's absolutely no translated string in this code which is generated server-side. While is should display the whole translated website, for SEO purposes.

To Reproduce

  1. Go to https://github.com/zeit/next.js/tree/canary/examples/with-react-i18next
  2. Use one of the methods to get the example on local
  3. Run the app and go to the browser
  4. Ctrl+U to get the source code of the page

Expected behavior

We should see all those strings in the source code:

This example integrates react-i18next for simple internationalization.
welcome to next.js
This example integrates react-i18next for simple internationalization.

test words for en

fire in the wind for en
You can either pass t function to child components.

Or wrap your component using the translate hoc provided by react-i18next.

Alternatively, you can use Trans component.

Go to page 2
Go to page 3 (no hoc)
@timneutkens timneutkens added help wanted good first issue Easy to fix issues, good for newcomers labels Sep 23, 2018
@ztanner
Copy link
Member

ztanner commented Sep 23, 2018

Going to take a look at this!

timneutkens pushed a commit that referenced this issue Sep 24, 2018
This fixes #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>
```
@lock lock bot locked as resolved and limited conversation to collaborators Sep 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good first issue Easy to fix issues, good for newcomers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants