Flash of content of default locale

krutijan1
0
krutijan1
commented a month ago

Version

6.3.1

Reproduction link

https://staging--apitalks-store.netlify.com/

Steps to reproduce

  • Open the link

  • Page loads ssr in Czech language, then during hydrate default locale is applied (English), it switches, then it switches back to Czech. Can you please help with how this thing could get going ?

What is expected ?

No flash of default locale during hydratation

What is actually happening?

Page loads ssr in Czech language, then during hydrate default locale is applied (English), it switches, then it switches back to Czech.

bug
0
rchl
578
rchl
commented a month ago

Would need to see your configuration.
Also, do you manually call setLocale in your code? If so, you shouldn't need to do that.

0
krutijan1
0
krutijan1
commented a month ago

Hi,

thanks for quick reply. I am using setLocale because I am using no_prefix strategy, the goal is to make according to vuex state dynamic set of locales, e.g. this first page should be meant Czech only, but another pages can be English only.

In AsyncData handler it works well, the nuxt generate generates correct ssr version, but the client flashes with default locale change, was thinking if passing store state from server to client before hydratation would force client not to switch to defaultLocale.

Not sure also, what would be the ideal approach to implement feature "according to vuex state per page render correct translated version of page", what is the idiomatic way, in which lifecycle events this should be performed etc.

Can I ask also, whether would hydratation bailing affects this ?

using locale switch like this:

await app.$i18n.setLocale(
      store.state.previews.previews[this.$route.params.id].language
);

I don't use any middlewares.

my nuxt.config.js here for nuxti18n:

const nuxti18nconf = {
  lazy: true,
  detectBrowserLanguage: false,
  langDir: 'locales/',
  locales: [
    { code: 'cs', file: 'cs.js' },
    { code: 'en', file: 'en.js' }
  ],
  defaultLocale: process.env.defaultLocale || 'en',
  strategy: 'no_prefix',
  vuex: {
    // Module namespace
    moduleName: 'i18n',

    // If enabled, current app's locale is synced with nuxt-i18n store module
    syncLocale: true,

    // If enabled, current translation messages are synced with nuxt-i18n store module
    syncMessages: true,

    // Mutation to commit to set route parameters translations
    syncRouteParams: true
  }
};

Appreciate any ideas.

Thanks

Jan

0
rchl
578
rchl
commented a month ago

Just to understand things better, what's the value of process.env.defaultLocale?

the nuxt generate generates correct ssr version

That's likely an important bit of information (the fact that you are using nuxt generate).
You could try returning the language you want to use from asyncData and then calling setLocale in beforeCreate hook.

0
krutijan1
0
krutijan1
commented a month ago

process.env.defaultLocale is not set, so it's having value 'en'.

You could try returning the language you want to use from asyncData and then calling setLocale in beforeCreate hook.

Couple observations here, the page is generated in right language, if I include in asyncData also setLocale change. await app.i18n.setLocale("cs"); In beforeCreate hook i cannot access this.$data as its not initialised yet? So I am passing it through store.

  // computed: {
  //   ...mapState({
  //     language: state => state.pages.language
  //   })
  // },
  async asyncData({ app }) {
    console.log("APP: before", app.store.state.i18n.locale);

    await app.store.commit("i18n/setLocale", "cs");
    await app.i18n.setLocale("cs"); // without this here, the nuxt generate will generate page localised in default locale (server-rendered-true)

    console.log("APP: after", app.store.state.i18n.locale);

    return {
      language: "cs"
    };

    // await store.commit("i18n/setLocale", "cs");
  },
  beforeCreate() {
    console.log("APP: before client", this.$store.state.i18n.locale); // here is en again in npm run dev environment.
    this.$store.commit("i18n/setLocale", "cs");
    this.$root.$i18n.setLocale(this.$store.state.i18n.locale);
    console.log("APP: after client");
  },

These are my observations so far

Thanks

0
rchl
578
rchl
commented a month ago

That approach seems to be more or less correct technically but not ideal because language change happens too late that way.

The asyncData doesn't run on the client for the initial, server-rendered request. That's expected but that's what makes this approach not ideal. And changing locale in beforeCreate seems to be a bit too late for avoiding flicker.

If you are wondering why store state is reverted to 'en' then what I said above is the reason - asyncData doesn't run on the client so neither store commit nor setLocale calls run. And nuxt-i18n itself initializes it to 'en' in your case.

Setting i18n/setLocale doesn't do anything for the module as module only sets and updates it when needed, it doesn't use that value as a source of locale to use.

I've toyed with using locale cookie to set and restore wanted locale, like:

        detectBrowserLanguage: {
          useCookie: true,
          fallbackLocale: "en"
        },
  async asyncData({ app }) {
      await app.i18n.setLocale('cs');
  },

But I've realized that this will likely not work with nuxt generate again…

So I think there might be no support for your current use case. For that to work, we would need a feature where one could force specified locale based on the value stored in the store.

0
krutijan1
0
krutijan1
commented 24 days ago

If you are wondering why store state is reverted to 'en' then what I said above is the reason - asyncData doesn't run on the client so neither store commit nor setLocale calls run. And nuxt-i18n itself initializes it to 'en' in your case.

Thanks for explanation, I have now more understanding of it.

Actually I have implemented your "playing around the cookie" and it works now so much better even with the nuxt generate (and netlify deployment static sites) as you can see here:

https://staging--apitalks-store.netlify.com/

On local development it is working even better, as its running the local server.

Will be watching the library for updates or maybe in future will deploy dedicated server for more proper serving.

So thanks again for your effort and patience.

Jan

0
rchl
578
rchl
commented 23 days ago

It doesn't work correctly on the first request to the site when a cookie is not set yet. So yeah, better but not ideal.

And to be fair, now that I think of it, the idea of setting locale from store wouldn't work well either, as this module's plugin would run before you would set store state from your page. So it would work the same as cookie…

0
Informations
Bug ReportOpen
#c346 - Created a month ago