i18n icon indicating copy to clipboard operation
i18n copied to clipboard

Code inside defineI18nLocaleDetector is not reached

Open mahfouzhseineweev opened this issue 7 months ago • 6 comments

Environment



Reproduction

  • nuxt.config.ts
export default defineNuxtConfig({
  ...(process.env.NODE_ENV === 'development' && {
    devServer: {
      https: {},
      host: '0.0.0.0',
      port: 443,
    }
  }),
  modules: [
    "@geeks.solutions/nuxt-sections",
    "@nuxt/image",
    "@nuxtjs/i18n",
    "@nuxtjs/tailwindcss",
    "nuxt-lazytube",
    "nuxt3-leaflet",
    "@pinia/nuxt"
  ],
  i18n: {
    detectBrowserLanguage: false,
    defaultLocale: "en",
    locales: [
      {
        name: "French",
        code: "fr",
        iso: "fr",
        file: "fr.js"
      },
      {
        name: "English",
        code: "en",
        iso: "en",
        file: "en.js"
      }
    ],
    langDir: "lang/",
    experimental: {
      localeDetector: 'localeDetector.ts'
    }
  },
  tailwindcss: {

  },
  css: [
    '~/assets/css/default.css'
  ],
  plugins: [
    '~/plugins/vue-dragscroll.js'
  ],
  devtools: { enabled: true },
  compatibilityDate: '2025-05-13',
  vite: {
    optimizeDeps: {
      include: ['quill', '@devdcodes9/quill-emojijs', 'quill-table-ui'],
    }
  },
  nitro: {
    compressPublicAssets: {
      gzip: true,
      brotli: true
    }
  }
})
  • localeDetector.ts inside i18n directory
console.log("Detector file loaded")

// Detect based on query, cookie, header
export default defineI18nLocaleDetector((event, config) => {

  console.log("Event", event)

  // try to get locale from query
  const query = tryQueryLocale(event, { lang: '' }) // disable locale default value with `lang` option
  if (query) {
    return query.toString()
  }

  // try to get locale from cookie
  const cookie = tryCookieLocale(event, { lang: '', name: 'i18n_redirected' }) // disable locale default value with `lang` option
  if (cookie) {
    return cookie.toString()
  }

  // try to get locale from header (`accept-header`)
  const header = tryHeaderLocale(event, { lang: '' }) // disable locale default value with `lang` option
  if (header) {
    return header.toString()
  }

  // If the locale cannot be resolved up to this point, it is resolved with the value `defaultLocale` of the locale config passed to the function
  return config.defaultLocale
})
  • nuxi prepare
  • nuxi dev

Describe the bug

I am trying to use the experimental localeDetector feature. The localeDetector file is loaded and confirmed by having Detector file loaded logged on the server console.

The problem I am facing is that defineI18nLocaleDetector is never called and no Event is logged. Am I missing something ?

Additional context

In the documentation I saw that the local detector function is called per request on the server, so why the code inside the defineI18nLocaleDetector is never reached

Logs

No errors logged at all

mahfouzhseineweev avatar May 29 '25 06:05 mahfouzhseineweev

The locale detector is only used for translations in nitro server routes, we may expand this in the future to allow configuring a custom locale detector for the whole project (both nuxt/nitro contexts). I understand the confusion, this should be documented more clearly.

BobbieGoede avatar May 31 '25 13:05 BobbieGoede

@mahfouzhseineweev Is your localeDetector.ts in the /i18n folder or in the root/elsewhere?

Image

@BobbieGoede Only nitro routes? That's weird. I see my localeDetector called from both nitro (/api/...) and Nuxt SSR (pages, like '/nl'). Or is Nuxt SSR also Nitro for you?

DavidDeSloovere avatar Jun 05 '25 10:06 DavidDeSloovere

@DavidDeSloovere Ah sorry you're right, I need to phrase this better.

The locale detector is called on each (nitro) request, this includes requests that involve server-side rendering, so what you're saying it correct.

The confusing part may be that the detected locale is not used much in the nuxt context, the name locale detector might suggest that it detects and sets the current locale within nuxt/vue, which is not the case. The detected locale is used when translating using server-side utilities like useTranslation.

The language detection within nuxt/vue (initial request, during navigation, client-side) essentially use a different locale detector, I am working towards a unified approach that can be opted-in (probably after v10 stable release).

BobbieGoede avatar Jun 05 '25 11:06 BobbieGoede

Thanks for clarifying.

I did have some code that seemed to call the detector in nitro middleware. Without calling useTranslation. So that why I see the calls on every request.

We want the locale/lang/culture on the context for calling other backends like CMS. Hope this is a correct way of doing that.

server\middleware\2.locale.ts

export default defineEventHandler(async (event) => {
  if (event.path.startsWith("/_")) {
    return;
  }

  const { locale: queryLocale } = getQuery(event);

  // @ts-expect-error locale is an async function in the context
  const i18nLocale = await event.context.i18n?.locale();

  const cultureCode = (queryLocale || i18nLocale || "nl").toString().toLowerCase(); // default to nl if no locale is provided
  const datoCmsLocale = getDatoLocaleFromCulture(cultureCode);

  event.context.cultureCode = cultureCode;
  event.context.locale = cultureCode;
...

DavidDeSloovere avatar Jun 05 '25 12:06 DavidDeSloovere

@BobbieGoede Is the documentation here up to date? We can't find a defineI18nLocaleDetector export even with the experimental option enabled. When manually linking a file with the experimental.localeDetector we see that the file is loaded, but the default export function there seems to never get executed. So this is in line with this issue. We have auto imports disabled though.

AdrianFahrbach avatar Sep 05 '25 17:09 AdrianFahrbach

@AdrianFahrbach Could you open a new issue with a minimal reproduction? It sounds like you're experiencing a separate issue.

BobbieGoede avatar Sep 05 '25 19:09 BobbieGoede