title: Hydrating SSR React App with react-i18next causes flicker
body: <p>I've been trying to get SSR to work with <code>react-i18next</code> for quite some time, the documentation is somewhat lacking so I've pieced together what I could from some other repos and their <a href="https://github.com/i18next/react-i18next/tree/master/example/razzle-ssr" rel="nofollow noreferrer">razzle-ssr example</a>.</p>
  
  <p>I have the server-side working, where I:</p>
  
  <ol>
  <li>Setup express, call the appropriate middleware, get the appropriate locale:</li>
  </ol>
  
  <pre><code>const app = express();
  await i18n
      .use(Backend)
      .use(i18nextMiddleware.LanguageDetector)
      .init(options)
  
  app.use(i18nextMiddleware.handle(i18n));
  app.use('/locales', express.static(`${appDirectory}/locales`));
  </code></pre>
  
  <ol start="2">
  <li>Get the DOM representation of the App given the request:</li>
  </ol>
  
  <pre><code>app.get('/*', req =&gt; {
      //...
      const html = ReactDOMServer.renderToString(
          &lt;I18nextProvider i18n={req.i18n}&gt;&gt;
              &lt;App /&gt;
          &lt;/I18nextProvider&gt;
      )
      // ...
  })
  </code></pre>
  
  <ol start="3">
  <li>Append the <code>initialI18nStore</code> to the request content:</li>
  </ol>
  
  <pre><code>const initialI18nStore = {};
  req.i18n.languages.forEach(l =&gt; {
    initialI18nStore[l] = req.i18n.services.resourceStore.data[l];
  });
  const initialLanguage = req.i18n.language;
  
  content = content.replace(
  /&lt;head&gt;/,
      `&lt;head&gt;
          &lt;script&gt;
          window.initialI18nStore = "${JSON.stringify(initialI18nStore)}";
          window.initialLanguage = "${initialLanguage.slice(0, 2)}";
      &lt;/script&gt;`,
  );
  </code></pre>
  
  <p>This works great when I <code>curl http://localhost:3000/</code> I get the correct DOM with the loaded/replaced translations</p>
  
  <p>The problem I encounter is hydration.</p>
  
  <p>I tried using <code>useSSR</code> with <code>Suspense</code> but couldn't seem to get it working. But I feel that will have fundamentally the same problem: <code>i18n</code> needs to initialize with languages before we <em>should</em> hydrate the app. Correct(?) </p>
  
  <p>I attempted to emulate the same thing as <code>useSSR</code> by waiting for the <code>client</code> <code>i18n</code> instance to be initialized before hydrating the app:</p>
  
  <pre><code>// client i18n.js
  import i18n from 'i18next';
  import { initReactI18next } from 'react-i18next';
  import Backend from 'i18next-http-backend';
  import LanguageDetector from 'i18next-browser-languagedetector';
  
  i18n
    .use(initReactI18next)
    .use(Backend)
    .use(LanguageDetector);
  
  const i18nInit = () =&gt; {
    return new Promise(resolve =&gt; {
      // @todo: shim in moment locale here
      i18n.init(options, () =&gt; resolve(i18n));
    });
  };
  
  export default i18nInit;
  </code></pre>
  
  <pre><code>// client index.js
  const renderApp = async () =&gt; {
    let i18n = await i18ninit();
    if (window.initialI18nStore) {
      i18n.services.resourceStore.data = window.initialI18nStore;
    }
    hydrate(&lt;BaseApp /&gt;, document.getElementById('root'));
  };
  
  renderApp();
  </code></pre>
  
  <p>The problem with this is: The app renders fine from the server-provided DOM representation. Then when I wait for the client <code>i18n</code> instance to initialize then hydrate the app, I get a huge style-less flicker, then it returns the same view as the DOM representation.</p>
  
  <p>I also tried to do the deferred rendering inside of a functional component:</p>
  
  <pre><code>const BaseApp = () =&gt; {
      const [render, setRender] = useState(false);
      useEffect( () =&gt; {
          await initI18();
          i18n.services.resourceStore.data = INITIALI18NSTORE;
          setRender(true);
      }, [])
      if(!render) return null;
      return &lt;App /&gt;
  }
  </code></pre>
  
  <p>But this causes similar, but instead of a style-less flicker, a white screen due to return <code>null</code>.</p>
  
  <p>Is there a concept I'm missing here? Or am I doing something out of order? How do I get a seamless transition from the server provided DOM+styles to my client provided ones with translations included?</p>