vue-i18nnuxt3.jsnuxt-i18n

Nuxt3 dynamic localized route paths


As from official documentation (https://v8.i18n.nuxtjs.org/guide/custom-paths and https://v8.i18n.nuxtjs.org/guide/lang-switcher) it seems impossible to have dynamic custom localized route paths with Nuxt3 + i18n.

The only way they suggest is with the compiler macros defineI18nRoute and definePageMeta and no available composable seem to address this.

To be clear my scenario is with this simple pages structure:

articles
--- [category].vue

In the [category].vue file I fetch articles from apis and I want then to update routing in order for the language switcher to switch to the correct slug.

If for example I navigate to /en/articles/nice-articles I want the switcher to switch to /it/articles/begli-articoli and not to /it/articles/nice-articles as it does by default. The problem is that I can know the begli-articoli italian slug only after fetching for the category from the apis.

Does it exist a native workaround that does not imply writing my own switcher?

It seems odd that Nuxt3 + i18n doesn't support this natively.


Solution

  • After some reading, the closest thing I found to this in the i18n module is this, but since you get your slugs dynamically from the API as well, this won't work for you, because you'll have to update the dynamic locales inside definePageMeta which is a compiler macro, so you can't update it in the runtime.

    I think your best bet is to write your own switcher, which should be really simple. Something along the lines of this:

    <template>
      ...
      <NuxtLink v-for="locale in availableLocales" :key="locale.code" :to="`/${locale.code}/articles/${articlesLocales[locale.code].slug}`">
        {{ locale.name }}
      </NuxtLink>
    
      ...
    </template>
    <script>
      const { locale, locales } = useI18n()
      const availableLocales = computed(() => {
        return (locales.value).filter(i => i.code !== locale.value)
      })
    
      const { data } = useFetch() // your API fetching logic...
    
      // change this based on your API strucuture
      const articlesLocales = ref((await data).value.locales)
    </script>
    

    I do not know how does your API response structure look like but I just assumed there's a locales object where keys are locale codes.