Skip to content

Commit

Permalink
fix: sync cookie when setting locale
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede committed Mar 24, 2024
1 parent eafe06b commit 34b3a02
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 21 deletions.
4 changes: 4 additions & 0 deletions specs/browser_language_detection/no_prefix.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ test('detection with cookie', async () => {
})
const { page } = await renderPage('/', { locale: 'en' })
const ctx = await page.context()
expect(await ctx.cookies()).toMatchObject([
{ name: 'my_custom_cookie_name', value: 'en', secure: true, sameSite: 'None' }
])

// click `fr` lang switch link
await page.locator('#set-locale-link-fr').click()
expect(await ctx.cookies()).toMatchObject([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ test('alwaysRedirect: no prefix', async () => {

// detect locale from navigator language
expect(await getText(page, '#lang-switcher-current-locale code')).toEqual('en')
expect(await ctx.cookies()).toMatchObject([{ name: 'i18n_redirected', value: 'en' }])

// click `fr` lang switch with nutlink
await page.locator('#set-locale-link-fr').click()
Expand Down
1 change: 1 addition & 0 deletions specs/issues/2262.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('#2262', async () => {
const ctx = await page.context()

expect(await getText(page, '#msg')).toEqual('Welcome')
expect(await ctx.cookies()).toMatchObject([{ name: 'i18n_redirected', value: 'en' }])

// change to `fr`
await page.locator('#fr').click()
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export default defineNuxtPlugin({
)
composer.setLocale = async (locale: string) => {
const localeSetup = isInitialLocaleSetup(locale)
const [modified] = await loadAndSetLocale(locale, i18n, runtimeI18n, localeSetup)
const modified = await loadAndSetLocale(locale, i18n, runtimeI18n, localeSetup)

if (modified && localeSetup) {
notInitialSetup = false
Expand Down Expand Up @@ -450,7 +450,7 @@ export default defineNuxtPlugin({
const localeSetup = isInitialLocaleSetup(locale)
__DEBUG__ && console.log('localeSetup', localeSetup)

const [modified] = await loadAndSetLocale(locale, i18n, runtimeI18n, localeSetup)
const modified = await loadAndSetLocale(locale, i18n, runtimeI18n, localeSetup)

if (modified && localeSetup) {
notInitialSetup = false
Expand Down
53 changes: 34 additions & 19 deletions src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,39 +107,57 @@ export async function loadAndSetLocale(
i18n: I18n,
runtimeI18n: ModulePublicRuntimeConfig['i18n'],
initial: boolean = false
): Promise<[boolean, string]> {
): Promise<boolean> {
const { differentDomains, skipSettingLocaleOnNavigate, lazy } = runtimeI18n
const opts = runtimeDetectBrowserLanguage(runtimeI18n)
const nuxtApp = useNuxtApp()

let ret = false
const oldLocale = getLocale(i18n)
const localeCodes = getLocaleCodes(i18n)

// sets the locale cookie if unset or not up to date
function syncCookie(locale: Locale = oldLocale) {
if (opts === false || !opts.useCookie) return
if (skipSettingLocaleOnNavigate) return

setCookieLocale(i18n, locale)
}

__DEBUG__ && console.log('setLocale: new -> ', newLocale, ' old -> ', oldLocale, ' initial -> ', initial)

// `newLocale` is unset or empty
if (!newLocale) {
return [ret, oldLocale]
syncCookie()
return false
}

// abort if different domains option enabled
// no change if different domains option enabled
if (!initial && differentDomains) {
return [ret, oldLocale]
syncCookie()
return false
}

if (oldLocale === newLocale) {
return [ret, oldLocale]
syncCookie()
return false
}

// call onBeforeLanguageSwitch
// call `onBeforeLanguageSwitch` which may return an override for `newLocale`
const localeOverride = await onBeforeLanguageSwitch(i18n, oldLocale, newLocale, initial, nuxtApp)
const localeCodes = getLocaleCodes(i18n)
if (localeOverride && localeCodes && localeCodes.includes(localeOverride)) {
if (localeOverride === oldLocale) {
return [ret, oldLocale]
if (localeOverride && localeCodes.includes(localeOverride)) {
// resolved `localeOverride` is already in use
if (oldLocale === localeOverride) {
syncCookie()
return false
}

newLocale = localeOverride
}

const i18nFallbackLocales = getVueI18nPropertyValue<FallbackLocale>(i18n, 'fallbackLocale')
// load locale messages required by `newLocale`
if (lazy) {
const i18nFallbackLocales = getVueI18nPropertyValue<FallbackLocale>(i18n, 'fallbackLocale')

const setter = (locale: Locale, message: Record<string, any>) => mergeLocaleMessage(i18n, locale, message)
if (i18nFallbackLocales) {
const fallbackLocales = makeFallbackLocaleCodes(i18nFallbackLocales, [newLocale])
Expand All @@ -149,19 +167,16 @@ export async function loadAndSetLocale(
}

if (skipSettingLocaleOnNavigate) {
return [ret, oldLocale]
return false
}

// set the locale
if (opts !== false && opts.useCookie) {
setCookieLocale(i18n, newLocale)
}
// sync cookie and set the locale
syncCookie(newLocale)
setLocale(i18n, newLocale)

await onLanguageSwitched(i18n, oldLocale, newLocale)

ret = true
return [ret, oldLocale]
return true
}

type LocaleLoader = () => Locale
Expand Down

0 comments on commit 34b3a02

Please sign in to comment.