Skip to content

Commit e8bd2d7

Browse files
authored
fix: reuse server-side locale detection (#3684)
1 parent edcd1a5 commit e8bd2d7

11 files changed

Lines changed: 174 additions & 2 deletions

File tree

pnpm-lock.yaml

Lines changed: 90 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ packages:
22
- docs
33
- playground
44
- specs/fixtures/*
5+
- specs/fixtures/issues/*
56
onlyBuiltDependencies:
67
- '@parcel/watcher'
78
- '@tailwindcss/oxide'

specs/fixtures/issues/3039/app.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<template>
2+
<div>
3+
<NuxtRouteAnnouncer />
4+
<NuxtPage />
5+
</div>
6+
</template>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"welcome": "Welcome"
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"welcome": "Bienvenue"
3+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { defineNuxtConfig } from 'nuxt/config'
2+
3+
export default defineNuxtConfig({
4+
modules: ['@nuxtjs/i18n'],
5+
i18n: {
6+
strategy: 'no_prefix',
7+
// When using prefix_except_default strategy
8+
detectBrowserLanguage: false,
9+
defaultLocale: 'fr',
10+
locales: [
11+
{ code: 'fr', file: 'fr.json', name: 'Français' },
12+
{ code: 'en', file: 'en.json', name: 'English' }
13+
]
14+
},
15+
compatibilityDate: '2024-07-23'
16+
})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "fixture-3039",
3+
"private": true,
4+
"scripts": {
5+
"build": "nuxt build",
6+
"dev": "nuxt dev",
7+
"generate": "nuxt generate",
8+
"preview": "nuxt preview"
9+
},
10+
"devDependencies": {
11+
"@nuxtjs/i18n": "latest",
12+
"nuxt": "latest"
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<script lang="ts" setup>
2+
const { locale, setLocale } = useI18n()
3+
4+
if (import.meta.server) {
5+
await setLocale('en')
6+
}
7+
</script>
8+
9+
<template>
10+
<div data-testid="locale">{{ locale }}</div>
11+
<p data-testid="welcome">{{ $t('welcome') }}</p>
12+
</template>

specs/issues/3039.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { test, expect, describe } from 'vitest'
2+
import { fileURLToPath } from 'node:url'
3+
import { createPage, setup } from '../utils'
4+
5+
describe('#3039', async () => {
6+
await setup({
7+
rootDir: fileURLToPath(new URL(`../fixtures/issues/3039`, import.meta.url)),
8+
browser: true
9+
})
10+
11+
test('does not detect and set locale client-side if locale has been detected and set server-side', async () => {
12+
// localized routing is disabled (no_prefix or defineI18nRoute(false))
13+
const page = await createPage('/')
14+
15+
// default locale is `fr` but has been set to `en` server-side
16+
expect(await page.getByTestId('locale').textContent()).toEqual('en')
17+
expect(await page.getByTestId('welcome').textContent()).toEqual('Welcome')
18+
})
19+
})

src/runtime/context.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export const useLocaleConfigs = () =>
2626
() => undefined
2727
)
2828

29+
export const useResolvedLocale = () => useState<string>('i18n:resolved-locale', () => '')
30+
2931
/**
3032
* @internal
3133
*/
@@ -91,6 +93,7 @@ export function createNuxtI18nContext(nuxt: NuxtApp, vueI18n: I18n, defaultLocal
9193
const getDomainFromLocale = (locale: string) =>
9294
domainFromLocale(runtimeI18n.domainLocales, useRequestURL({ xForwardedHost: true }), locale)
9395
const baseUrl = createBaseUrlGetter(nuxt, runtimeI18n.baseUrl, defaultLocale, getDomainFromLocale)
96+
const resolvedLocale = useResolvedLocale()
9497

9598
const ctx: NuxtI18nContext = {
9699
vueI18n,
@@ -112,6 +115,8 @@ export function createNuxtI18nContext(nuxt: NuxtApp, vueI18n: I18n, defaultLocal
112115
}
113116

114117
await nuxt.callHook('i18n:localeSwitched', { newLocale: locale, oldLocale })
118+
119+
resolvedLocale.value = locale
115120
},
116121
setLocaleSuspend: async (locale: string) => {
117122
if (!isSupportedLocale(locale)) return

0 commit comments

Comments
 (0)