Search code examples
javascriptvue.jsinternationalizationserver-side-renderingquasar-framework

How to change Server Side rendered HTML before Client Side rendering on Quasar?


I am new to Vue.js. And I want to use Vue I18n. The problem is that when I set the locale on Vue I18n I need to set HTML lang attribute to the same locale but I can't access document on SSR mode. So, how can I change Server Side Rendered HTML before Client Side rendering?

  if (process.env.CLIENT) // This does not seem good hydration.
    document.querySelector('html').setAttribute('lang', i18n.global.locale.value)

I tried to solve the problem with Meta plugin but lang attribute is 'en-US'.

useMeta(() => ({
  htmlAttr: {
    lang: i18n.global.locale.value
  }
}))

I don't want to use Quasar Language Pack because it limits my locales as it does not allow me to use some region codes.

So, I decided to set the Quasar Lang configuration no html attrs to true:

// quasar.config.js
    framework: {
      config: {
        lang: {
          noHtmlAttrs: true // add this
        }
      },

Even so, lang attribute disappears from HTML tag.


Solution

  • I got it to work by creating these functions:

    const qLangPacks = import.meta.glob(
      '../../node_modules/quasar/lang/(en-GB|es).js'
    )
    
    const qLocaleLangPacks = Object.entries(qLangPacks).map(([path, load]) => ({
      locale: path.slice(31, -3),
      load,
      path
    }))
    
    export async function qLoadLang(locale) {
      const [langLocale] = locale.split('-')
    
      const langPack = await qLocaleLangPacks
        .find((pack) => pack.locale === locale || pack.locale === langLocale)
        .load()
    
      return { ...langPack, isoName: locale }
    }
    
    

    Then simply call the function this way:

    import { Lang } from 'Quasar'
    (async () =>
      Lang.set(await qLoadLang(i18n.global.locale.value))
    )()
    

    Set this configuration:

    // quasar.config.js
        framework: {
          config: {},