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

Translations aren't loaded while isFallback = true #575

Open
alex-ragin opened this issue Apr 9, 2021 · 13 comments
Open

Translations aren't loaded while isFallback = true #575

alex-ragin opened this issue Apr 9, 2021 · 13 comments
Labels
bug Something isn't working Needs investigation Requires time to do some research

Comments

@alex-ragin
Copy link

Hey!

I noticed an issue that translations aren't loaded while in the isFallback state.

This is my getStaticPaths for one of the pages:

export const getStaticPaths: GetStaticPaths = async ({ locales }) => {
  const cities = await Api.getCities()
  let paths: Path[] = []

  locales?.forEach((locale) => {
    const localePaths = cities.map((city) => ({
      params: {
        citySlug: city.slug,
      },
      locale,
    }))
    paths = paths.concat(localePaths)
  })

  return {
    paths,
    fallback: true,
  }

getStaticProps:

export const getStaticProps: GetStaticProps<Props, Params> = async ({
  params,
}) => {
  let notFound = false

  if (!params || !params.citySlug) {
    notFound = true
    return {
      notFound,
    }
  }

  const home = await Api.getHome(params.citySlug)
  const city = await Api.getSingleCity(params.citySlug)

  if (!home || !city) {
    notFound = true
  }

  return {
    props: {
      home,
      city,
    },
    notFound,
    revalidate: 60,
  }
}

So when the new props are being fetched (isFallback is true), the translations aren't loaded. Once isFallback is false, then you can see all the translations.
image

image

For now, I'm just setting if (isFallback) return null - so that the screen is white while in fallback, but this is not that user friendly :(

Do you guys have any ideas on how to fix that?

@aralroca aralroca added bug Something isn't working Needs investigation Requires time to do some research labels Apr 12, 2021
@aralroca
Copy link
Owner

I don't know how the isFallback works underneath, so I'll have to investigate. Thank you for reporting it @alex-ragin

@TomasSestak
Copy link

Happens to me aswell, when using fallback Vercel doesn't let me deploy as the translations outside the page arent loaded

@aralroca
Copy link
Owner

aralroca commented Apr 14, 2021

translations are loaded in getStaticProps. I suppose that if you have the fallback, the pages that use the fallback do not load anything (translations or whatever you put inside the getStaticProps), is that so? Or would it has to load it in runtime instead of buildtime? I haven't used the fallback feature yet so I'm not sure how it works. Thanks!

@ztanner
Copy link

ztanner commented Apr 22, 2021

We've noticed this problem too and have used the workaround of returning null if isFallback: true, as suggested above.

I've created a minimal reproduction of this issue here: https://github.com/ztanner/next-translate-fallback-bug, with a description in the README. Hope it helps track down the cause - I'll see if I can help investigate as well.

@berndartmueller
Copy link
Contributor

I just encountered the same issue after upgrading from 1.0.5 to 1.0.7-canary.1.

@berndartmueller
Copy link
Contributor

Digging through the commits since 1.0.5, I was able to pin-point the issue down to https://github.com/vinissimus/next-translate/blob/8abc45855cdc95bed873657379499c758483829a/src/useTranslation.tsx#L11

useMemo() has the wrong dependencies. ctx.t should be listed in the deps instead of ctx.lang.

@aralroca Can you change it and release a hotfix patch version or should I create a PR?

@aralroca
Copy link
Owner

@berndartmueller ctx.t is different in every render. The useMemo with lang dependency was introduced here #574 to fix this issue #513 (comment) . Do you think that because of useMemo the isFallback=true does not work?

@berndartmueller
Copy link
Contributor

berndartmueller commented Apr 23, 2021

Yes, I changed the code locally and verified that this causes the issue with isFallback=true.

Why is ctx.t different on each render? ctx is a React context and the reference to it and ctx.t should be always the same. As long as the context is not manipulated through the provider.

Edit: What if the relevant code uses object destructing? Like following:

export default function useTranslation(defaultNs?: string): I18n {
  const { t, lang, ...ctx }  = useContext(I18nContext)


  return {
    ...ctx,
    lang,
    t: useMemo(() => wrapTWithDefaultNs(t, defaultNs), [
      t,
      lang,
      defaultNs,
    ]),
  }
}

Edit:

ctx.t is different in every render.

Maybe that's why there is currently a bug with useMemo. useMemo references the "outdated" ctx.t function, therefore having missing translations.

@berndartmueller
Copy link
Contributor

berndartmueller commented Apr 23, 2021

I was too hasty with my assumption. It seems this issue exists also before version 1.0.5.

Something is broken when Next.js generates this fallback page (during the initial build). Inspecting the page HTML source of a Next.js page with fallback clearly shows the missing translations. Pages that do not have a fallback (statically generated while building) do have proper translations.

The reason why it "seems" to work until version 1.0.6 is simply that client-side rendering replaces the statically generated fallback page with missing translations with a re-rendered page with translations.

The fix I proposed earlier (adapting useMemo dependencies) is just a way to fix the broken translations for CSR. It does not affect the fallback page itself.

@berndartmueller
Copy link
Contributor

I think I found the underlying issue:

See https://nextjs.org/docs/basic-features/data-fetching#fallback-pages

  • The page’s props will be empty.

Even though next-translate loads the needed translations within the webpack loader and puts it into the Next.js getStaticProps props, Next.js provides empty page props to the I18nProvider in AppWithTranslations.

My idea to circumvent this would be checking if router.isFallback: true and then loading the translations via loadNamespaces() in AppWithTranslations(). As this would be async, I'm not really sure yet how to do so.

@aralroca What do you think of this?

@richardhsueh
Copy link

I am not sure is it caused by the same reason but when i return { notFound: true } in getServerSideProps, the translation will also missing

export async function getServerSideProps(context) {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

  return {
    props: {}, // will be passed to the page component as props
  }
}

@aralroca
Copy link
Owner

I am not sure is it caused by the same reason but when i return { notFound: true } in getServerSideProps, the translation will also missing

export async function getServerSideProps(context) {
  const res = await fetch(`https://...`)
  const data = await res.json()

  if (!data) {
    return {
      notFound: true,
    }
  }

  return {
    props: {}, // will be passed to the page component as props
  }
}

Translations for 404 page should be added on /404, an example: https://github.com/vinissimus/next-translate/blob/21701d3af07713c080bb8b688b114dea1398f0e0/examples/complex/i18n.js#L6

@richardhsueh
Copy link

richardhsueh commented May 11, 2021

But for my page, the required translation is just under common namespace , and i did added '*': ['common'] in 18n.js . Also the translation only missing when go to page directly (paste the link to browser and press enter), if I navigate inside the website and land into the not found page, the translation will display correctly .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Needs investigation Requires time to do some research
Projects
None yet
Development

No branches or pull requests

6 participants