Skip to content

Commit 02e5f1f

Browse files
authored
fix!: trigger i18n:localeSwitched when pending locale switches (#3649)
1 parent 061b12b commit 02e5f1f

17 files changed

Lines changed: 71 additions & 76 deletions

File tree

docs/content/docs/02.guide/08.lang-switcher.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ export default defineNuxtConfig({
9292
<script setup lang="ts">
9393
const { finalizePendingLocaleChange } = useI18n()
9494

95-
const onBeforeEnter = () => {
96-
finalizePendingLocaleChange()
95+
const onBeforeEnter = async () => {
96+
await finalizePendingLocaleChange()
9797
}
9898
</script>
9999

@@ -160,8 +160,8 @@ definePageMeta({
160160
}
161161
})
162162

163-
route.meta.pageTransition.onBeforeEnter = () => {
164-
finalizePendingLocaleChange()
163+
route.meta.pageTransition.onBeforeEnter = async () => {
164+
await finalizePendingLocaleChange()
165165
}
166166
</script>
167167

docs/content/docs/02.guide/90.migrating.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ If this mode proves stable it will become the default in v11, please try it out
4343
### Lazy loading
4444
The `lazy` option has been removed and lazy loading of locale messages is now the default behavior.
4545

46-
### Signature changed for `finalizePendingLocaleChange()`{lang="ts"}
47-
The function signature for `finalizePendingLocaleChange()`{lang="ts"} has been corrected from `() => Promise<void>`{lang="ts-type"} to `() => void`{lang="ts-type"}.
48-
This change was made since the function does not rely on any async operations and should not be awaited, and should prevent unnecessary function coloring.
49-
5046
### Arguments changed `useLocaleHead()`{lang="ts"} and `$localeHead()`{lang="ts"}
5147
The `key` property has been removed and can no longer be configured, this is necessary for predictable and consistent localized head tag management.
5248

docs/content/docs/04.api/04.vue-i18n.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Returns browser locale code filtered against the ones defined in options.
5151

5252
- **Arguments**:
5353
- no arguments
54-
- **Returns**: `void`{lang="ts-type"}
54+
- **Returns**: `Promise<void>`{lang="ts-type"}
5555

5656
Switches locale to the pending locale, used when navigation locale switch is prevented by the [`skipSettingLocaleOnNavigate`](/docs/api/options#skipsettinglocaleonnavigate) option. See [Wait for page transition](/docs/guide/lang-switcher#wait-for-page-transition) for more information.
5757

specs/basic-usage-tests.ts

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test, expect } from 'vitest'
2-
import { $fetch, url } from './utils'
2+
import { $fetch, url, useTestContext } from './utils'
33
import {
44
assertLocaleHeadWithDom,
55
assetLocaleHead,
@@ -317,28 +317,40 @@ export function basicUsageTests() {
317317
test('<NuxtLink> triggers runtime hooks', async () => {
318318
const { page, consoleLogs } = await renderPage('/kr')
319319

320-
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch kr fr true'))).toBeTruthy()
321-
expect(consoleLogs.find(log => log.text.includes('onLanguageSwitched kr fr'))).toBeTruthy()
322-
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch fr fr false'))).toBeTruthy()
323-
324-
// current locale
325-
expect(await page.locator('#lang-switcher-current-locale code').innerText()).toEqual('fr')
320+
await page.waitForFunction(() => !window.useNuxtApp?.().isHydrating)
321+
consoleLogs.length = 0
326322

327323
// navigate to about page
328324
await page.locator('#link-about').clickNavigate()
329325
await page.waitForURL(url('/fr/about'))
330326

331-
// navigate to home page
332-
await page.locator('#link-home').clickNavigate()
333-
await page.waitForURL(url('/fr'))
327+
expect(consoleLogs[0].text).toEqual('i18n:beforeLocaleSwitch fr fr false')
334328
})
335329

336330
test('setLocale triggers runtime hooks', async () => {
331+
let output: string[] = []
332+
const ctx = useTestContext()
333+
ctx.serverProcess?.process?.on(
334+
'message',
335+
(msg: any) => msg.type === 'i18n:test-log' && msg.id === ctx.url?.split(':')[2]! && output.push(msg.data)
336+
)
337+
await new Promise(resolve => setTimeout(resolve, 1)) // wait for process to be ready
338+
output.length = 0
339+
337340
const { page, consoleLogs } = await renderPage('/kr')
338341

339-
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch kr fr true'))).toBeTruthy()
340-
expect(consoleLogs.find(log => log.text.includes('onLanguageSwitched kr fr'))).toBeTruthy()
341-
expect(consoleLogs.find(log => log.text.includes('onBeforeLanguageSwitch fr fr false'))).toBeTruthy()
342+
// overrides and redirects to `fr`
343+
expect(output).toMatchInlineSnapshot(`
344+
[
345+
"i18n:beforeLocaleSwitch kr fr true",
346+
"i18n:localeSwitched kr fr",
347+
"i18n:beforeLocaleSwitch fr fr false",
348+
"i18n:beforeLocaleSwitch fr fr true",
349+
]
350+
`)
351+
352+
// client-side enters on `fr` locale
353+
expect(consoleLogs.find(log => log.text.includes('i18n:beforeLocaleSwitch fr fr true'))).toBeTruthy()
342354

343355
// current locale
344356
expect(await page.locator('#lang-switcher-current-locale code').innerText()).toEqual('fr')

specs/fixtures/basic_usage/app.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const skipSettingLocale = useRuntimeConfig().public.i18n.skipSettingLocaleOnNavi
88
const pageTransition = {
99
name: 'my',
1010
mode: 'out-in',
11-
onBeforeEnter: () => finalizePendingLocaleChange()
11+
onBeforeEnter: async () => await finalizePendingLocaleChange()
1212
}
1313
</script>
1414

specs/fixtures/basic_usage_compat_4/app/app.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const skipSettingLocale = useRuntimeConfig().public.i18n.skipSettingLocaleOnNavi
88
const pageTransition = {
99
name: 'my',
1010
mode: 'out-in',
11-
onBeforeEnter: () => finalizePendingLocaleChange()
11+
onBeforeEnter: async () => await finalizePendingLocaleChange()
1212
}
1313
</script>
1414

specs/fixtures/common/components/LangSwitcher.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const switchLocalePath = useSwitchLocalePath()
4242
:id="`set-locale-link-${locale.code}`"
4343
:key="`b-${index}`"
4444
href="javascript:void(0)"
45-
@click.prevent="setLocale(locale.code)"
45+
@click.prevent="async () => await setLocale(locale.code)"
4646
>{{ locale.name }}</a
4747
>
4848
</section>

specs/fixtures/issues/1888/app.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
v-for="locale in availableLocales"
77
:id="locale.code"
88
:key="locale.code"
9-
@click="$i18n.setLocale(locale.code)"
9+
@click="async () => await $i18n.setLocale(locale.code)"
1010
>
1111
{{ locale.name }}
1212
</button>

specs/fixtures/issues/2590/app.vue

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,11 @@
55
</template>
66

77
<script setup lang="ts">
8-
const { locale, locales, setLocale } = useI18n()
8+
const _i18n = useI18n()
99
1010
const head = useLocaleHead()
1111
1212
useHead(() => ({
1313
htmlAttrs: head.value.htmlAttrs
1414
}))
15-
16-
const availableLocales = computed(() => {
17-
return (locales.value as LocaleObject[])
18-
.filter(item => {
19-
return item.code !== locale.value
20-
})
21-
.map(item => {
22-
return {
23-
label: item.name,
24-
key: item.code
25-
}
26-
})
27-
})
28-
29-
const currentLocale = computed(() => {
30-
return (locales.value as LocaleObject[]).filter(item => {
31-
return item.code === locale.value
32-
})
33-
})
34-
35-
function changeLocal(code: any) {
36-
setLocale(code)
37-
}
3815
</script>
Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import { defineNuxtPlugin } from '#imports'
22

3-
export default defineNuxtPlugin(nuxtApp => {
4-
nuxtApp.hook('i18n:beforeLocaleSwitch', ({ oldLocale, newLocale, initialSetup }) => {
5-
let overrideLocale = newLocale
3+
function log(...args: any[]) {
4+
if (import.meta.server && process.send) {
5+
process.send({ type: 'i18n:test-log', id: process.env.PORT, data: Array.from(args).join(' ') })
6+
// !import.meta.CI && console.log(...args)
7+
} else {
8+
console.log(...args)
9+
}
10+
}
611

7-
if (newLocale === 'kr') {
8-
overrideLocale = 'fr'
12+
export default defineNuxtPlugin(nuxtApp => {
13+
nuxtApp.hook('i18n:beforeLocaleSwitch', data => {
14+
if (data.newLocale === 'kr') {
15+
data.newLocale = 'fr'
916
}
1017

11-
console.log('onBeforeLanguageSwitch', oldLocale, overrideLocale, initialSetup)
12-
13-
if (overrideLocale !== newLocale) {
14-
return overrideLocale
15-
}
18+
log('i18n:beforeLocaleSwitch', data.oldLocale, data.newLocale, data.initialSetup)
1619
})
1720

1821
nuxtApp.hook('i18n:localeSwitched', ({ oldLocale, newLocale }) => {
19-
console.log('onLanguageSwitched', oldLocale, newLocale)
22+
log('i18n:localeSwitched', oldLocale, newLocale)
2023
})
2124
})

0 commit comments

Comments
 (0)