Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

detectBrowserLanguage Parameter configuration does not work #1632

Closed
1 of 2 tasks
senher opened this issue Nov 10, 2022 · 47 comments · Fixed by #2164 or #2276
Closed
1 of 2 tasks

detectBrowserLanguage Parameter configuration does not work #1632

senher opened this issue Nov 10, 2022 · 47 comments · Fixed by #2164 or #2276
Labels
browser language detection ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf v8

Comments

@senher
Copy link

senher commented Nov 10, 2022

Version

@nuxtjs/i18n:^8.0.0-beta.3
nuxt:3.0.0-rc.11

Nuxt configuration

Please change to [x] if relevant for this issue:

  • Applies to a site deployed to a static server (site generated with nuxt generate)
  • Applies to a site deployed to a server with a Node backend

@nuxtjs/i18n configuration

Reproduction Link

Steps to reproduce

i18n: {
    // ...
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n_redirected',
      redirectOn: 'root',  // recommended
    }
  },

What is Expected?

When I open the main site link in a browser in a different language, should he switch to the site in the corresponding language?
Is the cookie set to the corresponding language code?

What is actually happening?

They don't seem to be working properly

@rchl
Copy link
Collaborator

rchl commented Nov 10, 2022

Fill out all the requested information including specifying versions and providing reproduction.

@stephAc
Copy link

stephAc commented Nov 16, 2022

Hello, having the same issue where it seems that the browser language is not detected by the pluging and keeps on going for the defaultLocale config, It also applies to the static deployment.
Thank's for any info on this issue

@mjbates7
Copy link

Hello, I'm also experiencing the same issues as the above comments. It always goes back to the default locale rather than what is detected. I would have thought if the accept language detects the locale (and redirect is on) it would go to that {locale}/[...slug] for example. If no redirect then it should know what locale is detected.

Thank you

@markus-gx
Copy link

When using locale const { locale, availableLocales } = useI18n() it stays the same as the previous comments mentioned.
Inspected the request headers and they are different than the fallbackLocale configured. So no browser detectino is working. Running on beta.4 and Nuxt 3.0.0 Stable.

@Iamlowlo
Copy link

Iamlowlo commented Dec 5, 2022

I'm using Nuxt 3.0.0 and @nuxtjs/i18n 8.0.0-beta.6
Same issue with browser detection.
I tried to config with and without cookie usage with no luck. Even when useCookie is set to true, the cookie is not even set.
If defaultLocale is not set, project root route returns a 404 (cause that route doesn't exists indeed and needs a redirection that it's not happening)

The config I'm using is the following:

        modules: [
            '@nuxtjs/i18n',
        ],
        i18n: {
            strategy: 'prefix',
            locales: ['en-us', 'es'],
            detectBrowserLanguage: {
                useCookie: true,
                cookieKey: 'asdasd'
            },
            vueI18n: {
                legacy: false,
                locale: 'en-us',
                messages: {
                    'es': {
                        welcome: 'Bienvenido'
                    },
                    'en-us': {
                        welcome: 'Welcome'
                    }
                }
            }
        }

@rchl In my case is a brand new nuxt project and @nuxt/i18n is the only module included.

@rchl
Copy link
Collaborator

rchl commented Dec 5, 2022

I'm not up-to-date on what Nuxt 3 version supports. @kazupon will probably respond when he has some time.

@kazupon kazupon added the v8 label Dec 5, 2022 — with Volta.net
@madebyfabian
Copy link

madebyfabian commented Dec 5, 2022

Can confirm this is not working.

// nuxt.config.ts:
modules: [
[
  "@nuxtjs/i18n",
  {
    defaultLocale: "en",
    detectBrowserLanguage: {
      useCookie: true,
      alwaysRedirect: true,
      cookieKey: "i18n_redirected",
      cookieCrossOrigin: true,
      redirectOn: "root", // recommended
    },
    vueI18n: {
      strategy: "no_prefix",
      legacy: false,
      locale: "en",
      fallbackLocale: "en",
      messages: {
        en: {
          welcome: "Welcome",
        },
        de: {
          welcome: "Willkommen",
        },
      },
    },
  },
];
],

The app defaults to en even though I've set de successfully with the const { locale } = useI18n() like in the example. I also see that the cookie isn't even created. In I suppose beta.4 of the plugin the cookie was created, but it was still not working.

@tguelcan
Copy link

Still not working - any update?

@awacode21
Copy link

i can confirm i am experiencing the same issue on a brand new nuxt 3 project, @nuxtjs/i18n just added and used the recommended configuration for browser language detection with no effect.

Copy link
Collaborator

kazupon commented Dec 15, 2022

I appreciate your feedback.
However, we need a minimum reproducible environment to solve this issue.

Please provide a github repo or stackbliz 🙏

@madebyfabian
Copy link

madebyfabian commented Dec 16, 2022

@kazupon Here is a minimal reproduction.
https://stackblitz.com/edit/github-agwtyv?file=pages%2Findex.vue,nuxt.config.ts,package.json
It's a bare nuxt starter template, installed @nuxtjs/i18n beta 7.
There is a pages/index.vue. With the given config in nuxt.config.ts, I expect the language switch to work:

  • Detecting the browser language (in my case german) and changing it.
  • After I manually changed it to english/german and refresh the page, this setting should stay. And get read by the cookie. But it's reverting me back to the default.

Copy link
Collaborator

kazupon commented Dec 19, 2022

@madebyfabian
Thank you for your reporting!

I realized two things from your reporduction code.

  1. need locales options in nuxt.config.ts
  2. use setLocale, not locale
  1. need locales options in nuxt.config.ts

when we are using nuxtjs/i18n routing, we must always configure locales and defaultLocale. Even if it is no_prefix.

docs saying:
https://v8.i18n.nuxtjs.org/getting-started/basic-usage#configurations

  1. use setLocale, not locale

If we would change the cookie when you change the locale, we must use the nuxtjs/i18n API, setLocale.
The vue-i18n locale only allows us to change the vue-i18n locale.

docs saying at Lang Switcher
https://v8.i18n.nuxtjs.org/guide/lang-switcher

the below, I've modiefied your repro for detectBrowserLanguage and no_prefix strategy.
https://stackblitz.com/edit/github-agwtyv-jfubic?file=pages%2Findex.vue,nuxt.config.ts,app.vue

@madebyfabian
Copy link

@kazupon Thank you very much for explaining! Maybe I haven't read the docs correctly. For somebody who never used this module in nuxt 2, it was a bit confusing to get started.

I tried to implement your corrections from the repro in my current project and it works perfectly 😊.

  • Detects that my browser language is german on the first visit, sets the cookie + the current language to german and keeps it persistant.
  • After a hard refresh, it correctly reads the cookie, so even after I switch to another language, it correctly keeps that setting.

Though for some reason it does not work in stackblitz, but this could have many reasons, e.g. due to how the preview of stackblitz is crossorigin.

@awacode21
Copy link

awacode21 commented Dec 21, 2022

ok, so for me it is still not working. Don't understand what i am doing wrong.
My default language of the app is 'de' but my browser language of my browser settings is 'en'. So i would expect that when first visiting the page that it recognizes my 'en' browser language and sets this... but it is always loading with 'de'. And cookie set with 'de'. When i then change languages within the dropdown und reload page.. the cookie got the language which was selected in dropdown.... so do be honest i don't understand that behaviour.
My expectation would have been, page gets loaded in detected browser language 'en'.

Here is my stackblitz reproduction: https://stackblitz.com/edit/nuxt-starter-d4qefp @kazupon please have a look. I am desperate on this.

@awacode21
Copy link

when i print some console log on the onLanguageSwitched callback i can see that it switches at start from en to de.. so somehow it was able to recognize my language is 'en' but nevertheless decides to switch to default locale 'de'.

Copy link
Collaborator

kazupon commented Dec 21, 2022

@madebyfabian
I'm happy to hear that detectBrowserLanguage is correctly on your project.

Though for some reason it does not work in stackblitz, but this could have many reasons, e.g. due to how the preview of stackblitz is crossorigin.

We need to reload with stackblitz URL address hitting, not reload button

Copy link
Collaborator

kazupon commented Dec 21, 2022

@awacode21
I've tried to reproduce with your repro.
I seem that works correctly for my browser env.
for reload in stackbliz, we need to reload with stackblitz URL address hitting, not reload button

@awacode21
Copy link

awacode21 commented Dec 21, 2022

@kazupon i am already hitting the stackblitz url again instead of using the reload button but it behaves as i am describing it. Strange that for your browser it looks fine. i wonder what the difference is, as it is for me, clearly not working. Will try how it behaves with different browsers. Which browser are you using? I am using latest chrome on mac.

@awacode21
Copy link

no matter how often i read the documentation and no matter how often i do it exactly how it is documented. it simply does not work

@awacode21
Copy link

i checked for chrome, safari, firefox, opera... same behaviour on all browsers

@awacode21
Copy link

what i am also experiencing is.. after it already failed on first entry when no cookie was available to choose browser language instead of default language and set the cookie with the right value....... when i then change manually change to 'en'. And hit the stackblitz url again..... it shows englisch, but has hydration mismatch because on server it was rendered in german and on client it was rendered in englisch... so whatever is going on here, i think with this language detection there are some problems. i've already stripped complete logic out from my project to a simple stackblitz but still dealing with the issues.

Copy link
Collaborator

kazupon commented Dec 23, 2022

Hmm... I'm using latest chrome and macos tool.
I've tried to reproduce your stackbliz.
Unfortunately, I could not reproduce it. 😞

@notflip
Copy link

notflip commented Dec 23, 2022

@kazupon Could you share a stackblitz of the working version?

@ReDev1L
Copy link

ReDev1L commented Dec 25, 2022

I have same problem.
setLocale works.
Initial visit on localhost:3000 doesn't redirect to ru.localhost:3000, browser locale is 'ru' , but nuxt renders 'en'

Debug log:
#1708 (comment)

UPD:
Here function just ends, after filling redirect state. There is no navigateTo:

state.value = redirectPath // set reidrct path

And here interceptor takes wrong url according to my Debug log:

const domain = getDomainFromLocale(locale, normalizedLocales, nuxt)

Copy link
Collaborator

kazupon commented Feb 15, 2023

@quentint
Sorry for my late reply.
Thank you for your reproduction!

I’ve checked you reproduction.

Please try the latest edge channel version.
I've recently fixed the redirection & routing bugs.
I’ve installed and tried it on your repro.
You would see that it is working correctly.

@notflip
Copy link

notflip commented Feb 15, 2023

@quentint Sorry for my late reply. Thank you for your reproduction!

I’ve checked you reproduction.

Please try the latest edge channel version. I've recently fixed the redirection & routing bugs. I’ve installed and tried it on your repro. You would see that it is working correctly.

Does this mean that redirecting the / to a language route (/en for example) now also works on static websites? Or do you still need to use nginx/apache/caddy to have that redirect? Thanks for the work @kazupon

@quentint
Copy link

Please try the latest edge channel version. I've recently fixed the redirection & routing bugs. I’ve installed and tried it on your repro. You would see that it is working correctly.

Unfortunately I can't confirm 🙁
Do you have a link to a working reproduction?

Thanks!

@quentint
Copy link

quentint commented Mar 8, 2023

Redirection is now working 👍, but cookie is not created 🤔

@pk992
Copy link

pk992 commented Mar 10, 2023

the below, I've modiefied your repro for detectBrowserLanguage and no_prefix strategy.
https://stackblitz.com/edit/github-agwtyv-jfubic?file=pages%2Findex.vue,nuxt.config.ts,app.vue

Nothing will happen if the strategy is changed to prefix_except_default there - no redirect. Is this expected behaviour? How can we make i work?

@dword-design
Copy link

dword-design commented Mar 13, 2023

Same issue here. Redirect always redirects to default locale, not the browser locale. I use the prefix strategy. Minimal example can be found here:
https://github.com/dword-design/demo-nuxt3-i18n-redirect-always-default
The same project works with Nuxt 2

@ChrisGV04
Copy link

Same issue here. The default language of my Nuxt 3.3.1 app is "es" and it also supports "en", but If I use a browser with English, it does detect it on the logs but it doesn't redirect me to /en as it should and it sets the cookie to "es" for some reason.

My config

i18n: {
    lazy: true,
    langDir: 'lang',
    defaultLocale: 'es',
    locales: [
      { code: 'es', file: 'es.json' },
      { code: 'en', file: 'en.json' },
    ],

    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n',
      redirectOn: 'root',
    },

    vueI18n: {
      legacy: false,
    },
  },

Logs

load $i18n type definition plugin for composition mode composition.mjs:3
isSSR true , isSSG false i18n.mjs:53
useCookie on setup true i18n.mjs:54
defautlLocale on setup es i18n.mjs:55
detectLocale: initialLocale - es i18n.utils.mjs:146
detectBrowserLanguage: (path, strategy, alwaysRedirect, redirectOn, locale) - / prefix_except_default false root es i18n.internal.mjs:234
getLocaleCookie 
Object { useCookie: true, cookieKey: "i18n", localeCodes: (2) […] }
i18n.internal.mjs:168
detectBrowserLanguage: cookieLocale undefined i18n.internal.mjs:261
getBrowserLocale navigator.languages 
Array [ "en-US", "en" ]
i18n.internal.mjs:151
detectBrowserLanguage: browserLocale en i18n.internal.mjs:266
detectBrowserLanguage: (matchedLocale, cookieLocale, localeFrom) - en undefined navigator_or_header i18n.internal.mjs:268
detectBrowserLanguage: first finaleLocale (finaleLocale, lcoaleForm) - en undefined navigator_or_header i18n.internal.mjs:278
detectBrowserLanguage: vueI18nLocale es i18n.internal.mjs:285
detectBrowserLanguage: finalLocale !== vueI18nLocale en i18n.internal.mjs:291
detectLocale: detectBrowserLanguage (browserLocale, stat, reason, from) - en true undefined navigator_or_header i18n.utils.mjs:148
detectLocale: finaleLocale first (finaleLocale, strategy) - en prefix_except_default i18n.utils.mjs:159
detectLocale: finaleLocale second (finaleLocale, detectBrowserLanguage) - en 
Object { alwaysRedirect: false, cookieCrossOrigin: false, cookieDomain: null, cookieKey: "i18n", cookieSecure: false, fallbackLocale: "", redirectOn: "root", useCookie: true }
i18n.utils.mjs:171
detectLocale: finalLocale last (finalLocale, defaultLocale) - en es i18n.utils.mjs:179
detectLocale: finalLocale - en i18n.utils.mjs:183
first detect initial locale en i18n.mjs:83
final initial locale: en i18n.mjs:91
locale-changing middleware 
Object { fullPath: "/", hash: "", query: {}, name: "index___es", path: "/", params: {}, matched: (1) […], meta: Proxy, redirectedFrom: undefined, href: "/" }
 
Object { fullPath: "/", path: "/", query: {}, hash: "", name: "index___es", params: {}, matched: (1) […], meta: {}, redirectedFrom: undefined, href: "/" }
i18n.mjs:335
detectLocale: initialLocale - en i18n.utils.mjs:146
detectBrowserLanguage: (path, strategy, alwaysRedirect, redirectOn, locale) - / prefix_except_default false root en i18n.internal.mjs:234
getLocaleCookie 
Object { useCookie: true, cookieKey: "i18n", localeCodes: (2) […] }
i18n.internal.mjs:168
detectBrowserLanguage: cookieLocale undefined i18n.internal.mjs:261
getBrowserLocale navigator.languages 
Array [ "en-US", "en" ]
i18n.internal.mjs:151
detectBrowserLanguage: browserLocale en i18n.internal.mjs:266
detectBrowserLanguage: (matchedLocale, cookieLocale, localeFrom) - en undefined navigator_or_header i18n.internal.mjs:268
detectBrowserLanguage: first finaleLocale (finaleLocale, lcoaleForm) - en undefined navigator_or_header i18n.internal.mjs:278
detectBrowserLanguage: vueI18nLocale en i18n.internal.mjs:285
detectLocale: detectBrowserLanguage (browserLocale, stat, reason, from) - <empty string> false not_found_match undefined i18n.utils.mjs:148
detectLocale: finaleLocale first (finaleLocale, strategy) - <empty string> prefix_except_default i18n.utils.mjs:159
detectLocale: finaleLocale second (finaleLocale, detectBrowserLanguage) - es 
Object { alwaysRedirect: false, cookieCrossOrigin: false, cookieDomain: null, cookieKey: "i18n", cookieSecure: false, fallbackLocale: "", redirectOn: "root", useCookie: true }
i18n.utils.mjs:171
detectLocale: finalLocale last (finalLocale, defaultLocale) - es es i18n.utils.mjs:179
detectLocale: finalLocale - es i18n.utils.mjs:183
detect locale es i18n.mjs:348
localeSetup true i18n.mjs:350
setLocale: new ->  es  old ->  en  initial ->  true i18n.utils.mjs:102
detectRedirect: targetLocale ->  es i18n.utils.mjs:188
detectRedirect: route ->  
Object { fullPath: "/", hash: "", query: {}, name: "index___es", path: "/", params: {}, matched: (1) […], meta: Proxy, redirectedFrom: undefined, href: "/" }
i18n.utils.mjs:189
redirectPath on locale-changing middleware <empty string> i18n.mjs:363
navigate options  301 null false false i18n.utils.mjs:236
navigate isSSG false i18n.utils.mjs:237

@tmlmt
Copy link

tmlmt commented Apr 4, 2023

Hey @kazupon have you been able to work on this one? It's the only non-working feature I have at the moment, would love to see detectBrowserLanguage working again.

@oneart-dev
Copy link

oneart-dev commented May 19, 2023

Same issue for me, no redirect happening at all on latest version beta.12

@Vanger888
Copy link

Same for me. After debugging I found out that the locale is actually set according to the browser language, but the redirects don't work. In my case it is related to this check

function isI18nRouteDefined(route) {
  const i18nLocales = route.matched[0]?.meta.nuxtI18n;
  return i18nLocales ? Object.keys(i18nLocales).length > 0 : false;
}

route.matched[0]?.meta.nuxtI18n is undefined. As a result detectRedirect return an empty string. And the debug log provided by @ChrisGV04 confirms the same problem.

redirectPath on locale-changing middleware <empty string> i18n.mjs:363 .

Maybe we have a way to configure route metadata?
As a workaround, adding this code to pages will solve the problem

<script setup lang="ts">
definePageMeta({
  layout: 'default',
  nuxtI18n: {
    en: true,
    uk: true,
  },
});
</script>

But I don't think it should be done manually.

@unshame
Copy link

unshame commented Jun 3, 2023

I'm trying to get this feature to work with strategy: "prefix_except_default" and detectBrowserLanguage.redirectOn "no prefix"

I want the redirect to happen based on the user browser's language when they visit for the first time if they visit a no-prefix version of the website (default locale), but still allow them to change to other locales, including the default one.

What ends up happening is, unless I set alwaysRedirect, the redirect doesn't happen. And if I do set alwaysRedirect, then the I can't change the language to the default one, because it will redirect me back to the detected language.

Here's the reproduction: https://stackblitz.com/edit/github-vklszm?file=app.vue

I stepped through the code and it just seems completely broken to me.

detectLocale called here detects the correct locale

let initialLocale = detectLocale(

and passes that locale to createI18n

https://github.com/nuxt-modules/i18n/blob/9f9fd2ee9608f02fbd69b1e054d2c32e620ffeb1/src/runtime/plugins/i18n.ts#LL126C16-L126C26

then inside the router middleware detectLocale is called again

__DEBUG__ && console.log('locale-changing middleware', to, from)

which in turn calls detectBrowserLocale

? detectBrowserLanguage(route, context, nuxtI18nOptions, nuxtI18nInternalOptions, localeCodes, initialLocale, ssgStatus)

which, again, detects the locale correctly, but because now the vuei18n locale is set, it returns no locale https://github.com/nuxt-modules/i18n/blob/9f9fd2ee9608f02fbd69b1e054d2c32e620ffeb1/src/runtime/internal.ts#LL428C27-L428C41

which then changes the locale back to the default one.

What was the intended behavior here? I don't see how setting the detected locale in createI18n and then checking against that locale to decide if the redirect should happen or not could possibly work. I think a saner approach would be to redirect, unless the locale was explicitly changed by the user with switchLocalePath , respecting redirectOn.

Edit: looks like I can get it to work with the following changes:

  1. Don't pass locale to createI18n here https://github.com/nuxt-modules/i18n/blob/9f9fd2ee9608f02fbd69b1e054d2c32e620ffeb1/src/runtime/plugins/i18n.ts#LL126C16-L126C26
    This can also be done via a plugin
 export default defineNuxtPlugin(nuxtApp => {
   const i18n = nuxtApp.vueApp._context.provides[nuxtApp.vueApp.__VUE_I18N_SYMBOL__].global
  i18n.locale.value = undefined
})
  1. Manually set the i18n_redirected cookie when user clicks on a link with switchLocalePath
  2. Explicitly set nuxtI18n in definePageMeta of every page as described in the previous comment

@kazupon kazupon added ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf and removed need reproduction 💻 labels Jun 13, 2023
@kazupon kazupon reopened this Jun 15, 2023
@pmnzt
Copy link

pmnzt commented Jul 23, 2023

still facing all those same issues to this day! :(

@RomanSkrypnik
Copy link

Facing the same issue

@sync42johnny
Copy link

The 'prefix_except_default' and 'detectBrowserLanguage' features are still not working correctly.

@AhmedAbdelghffar
Copy link

AhmedAbdelghffar commented Jul 25, 2023

I'm facing the same issue, the redirection is made with 301 code, that means when the user open "/" on the first time it redirects to "/${default_lang}" permanently then the browser will cache this redirection for ever.

the redirection should be done with 302 instead to fix this issue

@gnidustotalus
Copy link

I'd like to bring attention to the fact that the 'prefix_except_default' and 'detectBrowserLanguage' features are still not functioning as expected. Despite the reported issues, the problem persists in the latest version.

I've noticed that the issue was marked as closed. However, I can confirm that the problem persists on my end. Could you please provide additional insights or reopen the issue for further investigation?

@kazupon, your expertise on this matter would be greatly appreciated. Could you shed some light on the status of this issue and whether there are any plans for resolution?

@BobbieGoede
Copy link
Collaborator

@gnidustotalus
If you're experiencing a similar issue to the one described here please open a new issue, preferably with a minimal reproduction. This issue was closed/resolved months ago, it's unlikely (but still possible) that the underlying cause of the issue is the same.

Locking this issue to prevent notification noise for the participants in here🙏

@nuxt-modules nuxt-modules locked as resolved and limited conversation to collaborators Jan 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
browser language detection ❗ p4-important Priority 4: bugs that violate documented behavior, or significantly impact perf v8
Projects
None yet