martinkr/next-export-i18n

How to handle hydration errors? SEO?

tomzag opened this issue ยท 8 comments

Hi,

when useBrowserDefault is set to true and the users browser language is different as set in defaultLang there will be fired hydrations errors ("Text content does not match server-rendered HTML."). This is expected as the client site renders a different language than generated on the server.

You can reproduce the issue on the example page (https://next-export-i18n-example.vercel.app/) if you change the browser language to something other than german (as here defaultLang is set to de).

Bildschirmfoto 2022-11-11 um 15 17 33

This is my first static next.js project so I'm wondering how to handle this?

I'm also wondering how SEO works for languages that are not set as defaultLang as this languages are not created as static files.

any updates on this problem ? i have hydration errors even for same language since translation key is not same as translation value ex:
"some sentence" : "some sentence."
in this example it's only the "." and yet next throws hydration error (which is indeed as expected) and i have no idea how to fix this

I am also very interested in a solution to this problem ;)

Hi everyone,

Thank you for reaching out. I will look into it.

Cheers

Found a "solution" to this issue, just pass the property suppressHydrationWarning to the element wrapping the translation:

<p suppressHydrationWarning>
    {t("some.key")}
</p>

If SEO is an issue for your project just enter to https://next-export-i18n-example.vercel.app/ and view page source, in every language the body text is the same to search engines regardless of the language you are in, so it is not advisable.

I'm guessing that t(...) can't be used until the client is loaded? I was seeing hydration errors any time I did a browser reload during dev basically saying that the key was not equal to the value from the translation file. I also tried using a string[] in my translation json (e.g. for paragraphs of content), which worked fine until I refreshed, which gave me a t(...).map is not a function. Based on what I was seeing, it looked like t(...) was just returning the key during pre-render.

What I did to get around this is ensure that the client is rendered first using useEffect. This fixed the hydration errors.

import { useState, useEffect } from "react";
import { useTranslation, useLanguageQuery } from "next-export-i18n";

export default TestPage = () => {
  const { t } = useTranslation();
  const [query] = useLanguageQuery();
  const [isClient, setIsClient] = useState<boolean>(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    isClient && (
      <div>
        <main>{t("home.hero.title")}</main>
      </div>
    )
  );
};

I'm guessing that t(...) can't be used until the client is loaded? I was seeing hydration errors any time I did a browser reload during dev basically saying that the key was not equal to the value from the translation file. I also tried using a string[] in my translation json (e.g. for paragraphs of content), which worked fine until I refreshed, which gave me a t(...).map is not a function. Based on what I was seeing, it looked like t(...) was just returning the key during pre-render.

What I did to get around this is ensure that the client is rendered first using useEffect. This fixed the hydration errors.

import { useState, useEffect } from "react";
import { useTranslation, useLanguageQuery } from "next-export-i18n";

export default TestPage = () => {
  const { t } = useTranslation();
  const [query] = useLanguageQuery();
  const [isClient, setIsClient] = useState<boolean>(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    isClient && (
      <div>
        <main>{t("home.hero.title")}</main>
      </div>
    )
  );
};

@martinkr But this is not the best solution.

@martinkr Do we have any solution for this yet?