#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 10:13:38 +00:00
|
|
|
import React from 'react'
|
2018-08-24 07:49:10 +00:00
|
|
|
import App, { Container } from 'next/app'
|
#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 10:13:38 +00:00
|
|
|
import { I18n as I18nR, I18nextProvider } from 'react-i18next'
|
|
|
|
import initialI18nInstance from '../i18n'
|
2018-08-24 07:49:10 +00:00
|
|
|
|
|
|
|
export default class MyApp extends App {
|
|
|
|
render () {
|
|
|
|
const { Component, pageProps } = this.props
|
#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 10:13:38 +00:00
|
|
|
const { i18n, initialI18nStore, initialLanguage } = pageProps || {}
|
2018-08-24 07:49:10 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Container>
|
#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 10:13:38 +00:00
|
|
|
<I18nextProvider
|
|
|
|
i18n={i18n || initialI18nInstance}
|
|
|
|
initialI18nStore={initialI18nStore}
|
|
|
|
initialLanguage={initialLanguage}
|
|
|
|
>
|
|
|
|
<React.Fragment>
|
|
|
|
<I18nR ns='common' wait>
|
|
|
|
{t => <h1>{t('common:integrates_react-i18next')}</h1>}
|
|
|
|
</I18nR>
|
|
|
|
<Component {...pageProps} />
|
|
|
|
</React.Fragment>
|
|
|
|
</I18nextProvider>
|
2018-08-24 07:49:10 +00:00
|
|
|
</Container>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|