martinkr / next-export-i18n

Internationalize (18n) next.js with true support for next export
MIT License
247 stars 37 forks source link

How to handle hydration errors? SEO? #50

Open tomzag opened 1 year ago

tomzag commented 1 year ago

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.

Nabeeh-AlSawaf commented 1 year ago

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

mr-t-Durden commented 1 year ago

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

martinkr commented 1 year ago

Hi everyone,

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

Cheers

EperezOk commented 1 year ago

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

<p suppressHydrationWarning>
    {t("some.key")}
</p>
macedomauriz commented 1 year ago

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.

dagoss commented 11 months ago

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>
    )
  );
};
SalahAdDin commented 9 months ago

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.

AgrYpn1a commented 8 months ago

@martinkr Do we have any solution for this yet?

Vanals commented 1 month ago

Is this a real problem do we really know that Google cannot crawl properly the website if we set the language client side?

An alternative could be to create static pages for each language, just for search engines.