Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .nuxtrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
setups.@nuxt/test-utils="4.0.3"
setups.@nuxt/test-utils="4.1.0"
2 changes: 1 addition & 1 deletion packages/nuxt/.nuxtrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
setups.@nuxt/test-utils="4.0.3"
setups.@nuxt/test-utils="4.1.0"
1 change: 1 addition & 0 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"devDependencies": {
"@nuxt/module-builder": "^1.0.3",
"@nuxt/schema": "catalog:",
"@nuxtjs/i18n": "^10.6.0",
"nuxt": "catalog: "
},
"keywords": [
Expand Down
7 changes: 4 additions & 3 deletions packages/nuxt/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ export default defineNuxtModule<ModuleOptions>({
})
})

// Injects a placeholder page for the renderer to silence warnings if the router integration is enabled.
nuxt.hooks.hookOnce('pages:extend', (pages) => {
if (pages.length) pages.push({ path: '/__compodium__/renderer', file: resolve('./runtime/renderer-placeholder.vue') })
// Placeholder page for the renderer to silence router warnings; re-added idempotently on pages rebuilds, with `name` and `meta.i18n: false` opting it out of `@nuxtjs/i18n` localization and redirects.
nuxt.hooks.hook('pages:extend', (pages) => {
if (!pages.length || pages.some(page => page.path === '/__compodium__/renderer')) return
pages.push({ path: '/__compodium__/renderer', name: 'compodium-renderer', file: resolve('./runtime/renderer-placeholder.vue'), meta: { i18n: false } })
})

if (nuxt.options.experimental?.typedPages) {
Expand Down
3 changes: 3 additions & 0 deletions packages/nuxt/test/fixtures/i18n/app/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<NuxtPage />
</template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<script setup lang="ts">
defineProps<{
label: string
}>()
</script>

<template>
<div>{{ label }}</div>
</template>
3 changes: 3 additions & 0 deletions packages/nuxt/test/fixtures/i18n/app/pages/[...slug].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div>catch-all</div>
</template>
3 changes: 3 additions & 0 deletions packages/nuxt/test/fixtures/i18n/app/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<div>i18n</div>
</template>
15 changes: 15 additions & 0 deletions packages/nuxt/test/fixtures/i18n/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default defineNuxtConfig({
modules: ['../../../src/module', '@nuxtjs/i18n'],

i18n: {
defaultLocale: 'en',
strategy: 'prefix',
// Runs the localization middleware during SSR too, so the tests can observe
// the redirect behavior the browser-side router applies on every navigation.
experimental: { nitroContextDetection: false },
locales: [
{ code: 'en', language: 'en-GB', name: 'English' },
{ code: 'it', language: 'it-IT', name: 'Italiano' }
]
}
})
5 changes: 5 additions & 0 deletions packages/nuxt/test/fixtures/i18n/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"private": true,
"name": "i18n",
"type": "module"
}
50 changes: 50 additions & 0 deletions packages/nuxt/test/i18n.nuxt.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { describe, it, expect, vi } from 'vitest'
import { setup, $fetch } from '@nuxt/test-utils/e2e'
import { joinURL } from 'ufo'
import { fileURLToPath } from 'node:url'
import { writeFile, rm } from 'node:fs/promises'
import { dirname } from 'pathe'

describe('i18n', async () => {
const rootDir = fileURLToPath(joinURL(dirname(import.meta.url), './fixtures/i18n'))

await setup({
rootDir,
dev: true,
port: 4547,
setupTimeout: 30000
})

it('renders the localized index page', async () => {
const html = await $fetch('/en')
expect(html).toContain('<div>i18n</div>')
})

describe('renderer', () => {
it('is mounted on the unprefixed path with strategy prefix', async () => {
const html = await $fetch('/__compodium__/renderer')
expect(html).toContain('<div id="compodium-default-preview"')
})

it('is not redirected by browser language detection', async () => {
const html = await $fetch('/__compodium__/renderer', {
headers: { 'accept-language': 'it-IT,it;q=0.9' }
})
expect(html).toContain('<div id="compodium-default-preview"')
})

it('survives a pages rebuild', async () => {
const tempPage = joinURL(rootDir, 'app/pages/temp.vue')
await writeFile(tempPage, '<template><div>temp page</div></template>\n')
try {
await vi.waitFor(async () => {
expect(await $fetch('/en/temp')).toContain('temp page')
}, { timeout: 15000, interval: 500 })
const html = await $fetch('/__compodium__/renderer')
expect(html).toContain('<div id="compodium-default-preview"')
} finally {
await rm(tempPage, { force: true })
}
})
})
})
1,469 changes: 1,219 additions & 250 deletions pnpm-lock.yaml

Large diffs are not rendered by default.