Zaay
Zaay

Reputation: 662

Nuxt i18n - How can I get current locale when generating routes?

I am having some problems while generating dynamic routes for Nuxtjs. I have a list of products that I retrieve from the API and I am generating single pages for them.

Everything works flawlessly for the default locale (I am using Nuxt i18n).

The problem is, that I want to call a different API if in another locale. I have tried many things to get the current locale into the routes() method but without any luck.

My code is:

  generate: {
    target: "static",
    crawler: true,

    routes: function () {

      /* I WANT TO GET CURRENT LOCALE HERE FROM i18n
       so that I can call the correct API endpoint */

      let products = axios.get('https://example.com/v1/get-products').then((res) => {
        return res.data.map(product => {
          return {
            route: '/product/' + product.slug,
            name: 'product',
            payload: product
          }
        })
      })
      return Promise.all([products]).then(values => {
        return [...values[0]]
      })
      
    }
  }

Upvotes: 3

Views: 8958

Answers (3)

kissu
kissu

Reputation: 46824

As told you here by Rafał Chłodnicki who is the maintainer of the i18n module, this is not something possible (you can't know the current locale at build time).

And as explained in my comment, the only way would still to generate all of the locales ahead of time, then let the end user arrive on the given page regarding the browser language detection.

Something like this in your nuxt.config.js should do the trick

export default {
  generate: {
    target: 'static',
    crawler: true,

    routes: async () => {
      const availableLocales = ['fr', 'es', 'en']

      const results = await Promise.all(
        availableLocales.map(async (locale) => {
          const products = await axios.get(
            `https://example.com/v1/get-products/${locale}`
          )
          return products.data.map((product) => {
            return {
              route: `/product/${product.slug}`,
              name: 'product',
              payload: product,
            }
          })
        })
      )
      return results

      // return Promise.all([results]).then((values) => {
      //   return [...values[0]]
      // })
    },
  },
}

Upvotes: 4

Merlin
Merlin

Reputation: 99

In your case it does not look like you nee the function localePath so the easy way will be to import the i18n config like this :

nuxt.config.js

import i18n from 'i18n.config.js' //https://i18n.nuxtjs.org/basic-usage/

export default {
  i18n,
  generate: {
    target: "static",
    crawler: true,

    routes: function () {
       let products = i18n.locale.map((locale) => {
         axios.get(`https://example.com/v1/get-products?lang=${locale.code}`).then((res) => {
          return res.data.map(product => {
            return {
              route: '/product/' + product.slug,
              name: 'product',
              payload: product
            }
          })
        })
       })
       return Promise.all(products.flat()).then(values => {
        return [...values[0]]
      })
      
    }
  }
}

I've tried to access i18n instance from the generate function, from my point of view it's impossible (I will make two more post about this so it does not poluate this response)

Upvotes: 1

Merlin
Merlin

Reputation: 99

THIS RESPONSE DOES NOT WORK AND IS HERE ONLY TO SAVE YOU SOME TIME :)

  1. I've tried to use an accessor set from the generate:before nuxt.config.ts
import i18n from './i18n.conf'
import { generate, setGenerator } from './generate.config'

const nuxtConfig: NuxtConfig = {
  hooks: {
    generate: {
      before(this: any, options: any) {
        setGenerator(this, options)
      },
    },
  },
  modules: [
    '@nuxtjs/i18n', // https://i18n.nuxtjs.org/
  ],

  generate,
  i18n,
}

export default nuxtConfig

generate.config.ts

import { Context } from '@nuxt/types'
import { NuxtOptionsGenerate } from '@nuxt/types/config/generate'

let generator: Context | null = null
let generatorConfig: any | null = null

const setGenerator = (hookGenerator: Context, hookGeneratorConfig: any) => {
  generator = hookGenerator
  generatorConfig = hookGeneratorConfig
} 

const generate: NuxtOptionsGenerate = {
  routes: async () => {
    // Here you have access to generator that contain a nuxt instance
    // But i18n is not accessible from it ;(
    generator.nuxt // it exists
    generatorConfig.i18n // i18n conf from nuxt.config.ts
  }
}
  1. I've try to use a module as well, same issue

In the end I've juste coded the localePath function so I was able to use it in the generate and the sitemap. (by the way it make no sens that i18n is not using the real route name and rather remove the _ from the name)

Upvotes: 0

Related Questions