nuxt-modules / i18n

I18n module for Nuxt
https://i18n.nuxtjs.org
MIT License
1.74k stars 480 forks source link

Using `v-html` with `$t` is broken for `SSG` #2626

Open noah-nuebling opened 10 months ago

noah-nuebling commented 10 months ago

Environment


Reproduction

  1. Checkout this repo to your computer (I couldn't get it to work on Stackblitz)
    git clone git@github.com:noah-nuebling/bug-repro-nuxt-3-i18n-ssg-v-html.git
  2. Render and serve the site statically
    pnpm install; pnpm generate; npx serve .output/public/
  3. View the site by opening http://localhost:3000/ in your browser.
  4. Click the "Make German" button. The text on the page will switch to German, and the url will change to http://localhost:3000/de-DE. In the background this will set a cookie that your language preference is German.
  5. Open the base url http://localhost:3000/ again. This will now redirect you to http://localhost:3000/de-DE, because of the cookie. But the text on the page will remain English instead of changing to German.

Describe the bug

When users are redirected to a different language page, then the translations don't update correctly when using v-html with $t while using Static Site Generation.

Additional context

Logs

No response

noah-nuebling commented 10 months ago

I think #1888 might be related

noah-nuebling commented 10 months ago

I found a workaround. It's also in the reproduction repo under /plugins/language-redirect-fix.js

BobbieGoede commented 10 months ago

Thanks for investigating and reporting this issue! This issue sounds similar to something I ran into while debugging a different issue in this comment.

Perhaps you have already tried wrapping the element that uses v-html in <ClientOnly>, this may also work as a workaround but renders after load which may not suit your use case.

I'm not sure yet what the root cause of this issue is, will look into this more later.

jheng-jie commented 5 months ago

I encountered a similar issue, which might be related to this one.

// After executing generate, there is a pre-translation.
<h1>{{ t("website.title") }}</h1>

// But after using v-t generate, it is blank.
// After CSR, the translation appears, but this disrupts SEO.
<h1 v-t="'website.title'" />