Next-translate: No SSR lang in useTranslation

Created on 30 Oct 2020  ·  16Comments  ·  Source: vinissimus/next-translate

After migration to 0.19, and making the required changes, lang is undefined during the SSR. It is the expected string again during the CSR.

bug

All 16 comments

@darren-charterindex thanks to report it!

@darren-charterindex can you provide the generated page code?

I tried with getStaticProps and with getServerSideProps and looks that is working fine. Are you using a getInitialProps? Or some HOC wrapping your page?

I'm using a function component with no getStaticProps, getServerSideProps, or HOC. Just using the useTranslation hook, from next-translate/useTranslation.

Ok, in this case, it should use a getStaticProps internally if you are using the "build step".

This should work:

image

Or are you using the appWithI18n alternative?

The generated code:

import I18nProvider from 'next-translate/I18nProvider'
import React from 'react'
import C from '../../../../src/_pages/yachts/[slug]'

export default function Page({ _ns, _lang, ...p }){
  return (
    <I18nProvider
      lang={_lang}
      namespaces={_ns}  

    >
      <C {...p} />
    </I18nProvider>
  )
}

Page = Object.assign(Page, { ...C })



export const getServerSideProps = async ctx => {
    const _lang = ctx.locale || ctx.router?.locale || 'en'
  const ns0 = await import(`../../../../locales/${_lang}/common.json`).then(m => m.default)
const ns1 = await import(`../../../../locales/${_lang}/search.json`).then(m => m.default)
  const _ns = { 'common': ns0, 'search': ns1 }

    let res = {}
    if(typeof res.then === 'function') res = await res

    return { 
      ...res, 
      props: {
        ...(res.props || {}),
        _ns,
        _lang,
      }
    }
  }

I am using the build step, and not the appWithI18n alternative.

Contrary to my first report, actually on SSR, it logs three times when console.log(useTranslation()) inside page component.

First time:

{ lang: undefined, t: [Function: t] }
[next-translate] "common:loading" is missing in current namespace configuration. Try adding "loading" to the namespace "common".
... etc

Second time (there is no next-translate errors this time):

{ lang: undefined, t: [Function: t] }

Third time (with populated lang):

{ lang: 'en', t: [Function: t] }

The only HOC wrapping the _app.js is import { withApollo } from 'next-apollo'

Sorry @darren-charterindex , but I can't reproduce it, all the time logs only 1 console.log showing the lang well ( SSR and CSR), I tried many combinations ... It would be very helpful if you could share a reproducible example. Thank you very much! 🙏

No problem @aralroca, thank you for taking a look, and thank you for next-translate 👍

I suspect it's a race condition, with Apollo hydrating the state.

I've reverted to 0.18.0 for now as this is working fine.

@darren-charterindex Have you tried to use the useRouter?

import { userRouter } from 'next/router'
// ...
const { locale } = useRouter()
console.log({ lang: locale })

useRouter works as expected, with each console.log(locale) populated.

This solves the issue of requiring the locale for other purposes, such as for querying a localised api.

However next-translate still isn't happy on the SSR first pass, with the errors:

[next-translate] "common:loading" is missing in current namespace configuration. Try adding "loading" to the namespace "common".
...

I've also noticed upon moving to 0.19.0 that the build changed it's interpretation of some pages. Where previously built as λ (Lambda), becoming ● (SSG)

0.19.1-canary.1 fixes the issue. Thank you 👍

0.19.1-canary.1 fixes the issue. Thank you 👍

I was just going to ask you. Very happy to hear it! Thank you for reporting the issue! 😊 Besides the warning log, the lang of useTranslate is also ok?


I've also noticed upon moving to 0.19.0 that the build changed it's interpretation of some pages. Where previously built as λ (Lambda), becoming ● (SSG)

Yes, in this release we have changed the way the pages are assembled. Now in fact the structure is exactly the same as you have in _pages, only we load the namespaces that each page needs using the "loaders" that Next.js has (getStaticProps, getServerSideProps, or getInitialProps).

It may seem like a backward step... Pages, before, were duplicated for each language, becoming totally static without needing SSG. However, this blocked further evolution of the library by adapting the i18n changes that Next.js is developing. I think it is a small cost to pay, since from static to SSG there is not much difference either, only that it is generated at the moment Next.js does its internal build.

Thanks to this, in version 1.0.0 of next-translate we probably don't need the "build step" anymore, since now the next step that Next.js team is developing is to provide a way to load the translations, which is exactly why in version 0.19 we still need the "build step".

All these steps are being taken by listening to people how they use i18n in their projects, naturally, if you see that we are taking a wrong step, you can contribute your ideas on how to evolve the library in this issue.

Was this page helpful?
0 / 5 - 0 ratings