@fluenti/nuxt 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/detectors-BnmzZTww.cjs +2 -0
- package/dist/detectors-BnmzZTww.cjs.map +1 -0
- package/dist/detectors-CAqp_VCN.js +100 -0
- package/dist/detectors-CAqp_VCN.js.map +1 -0
- package/dist/devtools.d.ts +31 -0
- package/dist/devtools.d.ts.map +1 -0
- package/dist/isr-validation.d.ts +14 -0
- package/dist/isr-validation.d.ts.map +1 -0
- package/dist/locale-head-BuSO-fCZ.js +88 -0
- package/dist/locale-head-BuSO-fCZ.js.map +1 -0
- package/dist/locale-head-D1NAUQc8.cjs +2 -0
- package/dist/locale-head-D1NAUQc8.cjs.map +1 -0
- package/dist/module.cjs +1 -1
- package/dist/module.cjs.map +1 -1
- package/dist/module.d.ts +18 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +231 -46
- package/dist/module.js.map +1 -1
- package/dist/page-extend-BrPO2RhM.js +36 -0
- package/dist/page-extend-BrPO2RhM.js.map +1 -0
- package/dist/page-extend-tRXsujtK.cjs +2 -0
- package/dist/page-extend-tRXsujtK.cjs.map +1 -0
- package/dist/page-meta-transform.d.ts +17 -0
- package/dist/page-meta-transform.d.ts.map +1 -0
- package/dist/runtime/client.cjs +1 -1
- package/dist/runtime/client.cjs.map +1 -1
- package/dist/runtime/client.js +2 -2
- package/dist/runtime/components/NuxtLinkLocale.cjs +1 -1
- package/dist/runtime/components/NuxtLinkLocale.cjs.map +1 -1
- package/dist/runtime/composables.cjs +1 -1
- package/dist/runtime/composables.cjs.map +1 -1
- package/dist/runtime/composables.d.ts +46 -0
- package/dist/runtime/composables.d.ts.map +1 -1
- package/dist/runtime/composables.js +55 -13
- package/dist/runtime/composables.js.map +1 -1
- package/dist/runtime/define-i18n-route.cjs +2 -0
- package/dist/runtime/define-i18n-route.cjs.map +1 -0
- package/dist/runtime/define-i18n-route.d.ts +27 -0
- package/dist/runtime/define-i18n-route.d.ts.map +1 -0
- package/dist/runtime/define-i18n-route.js +6 -0
- package/dist/runtime/define-i18n-route.js.map +1 -0
- package/dist/runtime/detectors/cookie.d.ts.map +1 -1
- package/dist/runtime/detectors/domain.cjs +2 -0
- package/dist/runtime/detectors/domain.cjs.map +1 -0
- package/dist/runtime/detectors/domain.d.ts +9 -0
- package/dist/runtime/detectors/domain.d.ts.map +1 -0
- package/dist/runtime/detectors/domain.js +15 -0
- package/dist/runtime/detectors/domain.js.map +1 -0
- package/dist/runtime/detectors/header.d.ts.map +1 -1
- package/dist/runtime/detectors/index.d.ts +1 -1
- package/dist/runtime/detectors/index.d.ts.map +1 -1
- package/dist/runtime/detectors/query.d.ts.map +1 -1
- package/dist/runtime/index.cjs +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +5 -5
- package/dist/runtime/locale-head.d.ts +3 -0
- package/dist/runtime/locale-head.d.ts.map +1 -1
- package/dist/runtime/middleware/locale-redirect.cjs +1 -1
- package/dist/runtime/middleware/locale-redirect.cjs.map +1 -1
- package/dist/runtime/middleware/locale-redirect.js +1 -1
- package/dist/runtime/page-extend.d.ts +21 -5
- package/dist/runtime/page-extend.d.ts.map +1 -1
- package/dist/runtime/plugin.cjs +1 -1
- package/dist/runtime/plugin.cjs.map +1 -1
- package/dist/runtime/plugin.d.ts.map +1 -1
- package/dist/runtime/plugin.js +55 -23
- package/dist/runtime/plugin.js.map +1 -1
- package/dist/runtime/server/locale-redirect.cjs +2 -0
- package/dist/runtime/server/locale-redirect.cjs.map +1 -0
- package/dist/runtime/server/locale-redirect.d.ts +12 -0
- package/dist/runtime/server/locale-redirect.d.ts.map +1 -0
- package/dist/runtime/server/locale-redirect.js +51 -0
- package/dist/runtime/server/locale-redirect.js.map +1 -0
- package/dist/runtime/standalone-composables.cjs +2 -0
- package/dist/runtime/standalone-composables.cjs.map +1 -0
- package/dist/runtime/standalone-composables.d.ts +6 -0
- package/dist/runtime/standalone-composables.d.ts.map +1 -1
- package/dist/runtime/standalone-composables.js +34 -0
- package/dist/runtime/standalone-composables.js.map +1 -0
- package/dist/sitemap.d.ts +24 -0
- package/dist/sitemap.d.ts.map +1 -0
- package/dist/types.d.ts +210 -13
- package/dist/types.d.ts.map +1 -1
- package/llms-full.txt +411 -0
- package/llms-migration.txt +201 -0
- package/llms.txt +103 -0
- package/package.json +5 -4
- package/dist/detectors-CFJvuwzi.cjs +0 -2
- package/dist/detectors-CFJvuwzi.cjs.map +0 -1
- package/dist/detectors-DhkfHBHr.js +0 -84
- package/dist/detectors-DhkfHBHr.js.map +0 -1
- package/dist/locale-head-BfsESdd7.cjs +0 -2
- package/dist/locale-head-BfsESdd7.cjs.map +0 -1
- package/dist/locale-head-CqUlvy3O.js +0 -38
- package/dist/locale-head-CqUlvy3O.js.map +0 -1
- package/dist/page-extend-DJ7wpuVj.js +0 -25
- package/dist/page-extend-DJ7wpuVj.js.map +0 -1
- package/dist/page-extend-OvV-ZhFB.cjs +0 -2
- package/dist/page-extend-OvV-ZhFB.cjs.map +0 -1
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,uBAAuB,GAAG,oBAAoB,GAAG,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/llms-full.txt
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# @fluenti/nuxt
|
|
2
|
+
|
|
3
|
+
> Nuxt 3 module for Fluenti — locale-prefixed routing, locale detection, SEO head helpers, and NuxtLinkLocale component.
|
|
4
|
+
|
|
5
|
+
@fluenti/nuxt integrates Fluenti i18n into Nuxt 3 with four URL routing strategies, an ordered locale detection chain, automatic vite-plugin registration, SEO head helpers (hreflang, og:locale), a locale-aware NuxtLinkLocale component, and full SSR/SSG/SPA/ISR support. Compatible with Nuxt >= 3.0.0.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add @fluenti/nuxt @fluenti/core @fluenti/vue
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
// nuxt.config.ts
|
|
17
|
+
export default defineNuxtConfig({
|
|
18
|
+
modules: ['@fluenti/nuxt'],
|
|
19
|
+
fluenti: {
|
|
20
|
+
locales: ['en', 'ja', 'zh'],
|
|
21
|
+
defaultLocale: 'en',
|
|
22
|
+
strategy: 'prefix_except_default',
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Preferred Usage (compile-time first)
|
|
28
|
+
|
|
29
|
+
When writing Nuxt application code with Fluenti, prefer compile-time APIs:
|
|
30
|
+
|
|
31
|
+
1. `v-t` directive — `<p v-t>Hello {name}</p>` (Vue templates, zero runtime cost)
|
|
32
|
+
2. t`` tagged template — t`Hello {name}` (primary compile-time API)
|
|
33
|
+
3. `<Trans>` / `<Plural>` / `<Select>` — rich text with inline markup
|
|
34
|
+
4. `msg` tagged template — outside components (route meta, stores)
|
|
35
|
+
5. `useI18n().t()` — runtime fallback for dynamic keys only
|
|
36
|
+
|
|
37
|
+
❌ AVOID: `t('some.key')` as the default — this is a legacy i18n pattern.
|
|
38
|
+
|
|
39
|
+
## Module Options
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
// nuxt.config.ts
|
|
43
|
+
export default defineNuxtConfig({
|
|
44
|
+
fluenti: {
|
|
45
|
+
// Required
|
|
46
|
+
locales: ['en', 'ja', 'zh'],
|
|
47
|
+
defaultLocale: 'en',
|
|
48
|
+
|
|
49
|
+
// Routing
|
|
50
|
+
strategy: 'prefix_except_default',
|
|
51
|
+
|
|
52
|
+
// Locale detection
|
|
53
|
+
detectOrder: ['path', 'cookie', 'header'],
|
|
54
|
+
detectBrowserLanguage: {
|
|
55
|
+
useCookie: true,
|
|
56
|
+
cookieKey: 'fluenti_locale',
|
|
57
|
+
fallbackLocale: 'en',
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
// Build
|
|
61
|
+
autoVitePlugin: true,
|
|
62
|
+
componentPrefix: '',
|
|
63
|
+
|
|
64
|
+
// ISR (Incremental Static Regeneration)
|
|
65
|
+
isr: { enabled: true, ttl: 3600 },
|
|
66
|
+
},
|
|
67
|
+
})
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Option | Type | Default | Description |
|
|
71
|
+
|--------|------|---------|-------------|
|
|
72
|
+
| `locales` | `string[]` | — | Supported locale codes (required) |
|
|
73
|
+
| `defaultLocale` | `string` | `'en'` | Default locale code (required) |
|
|
74
|
+
| `strategy` | `Strategy` | `'prefix_except_default'` | URL routing strategy |
|
|
75
|
+
| `detectOrder` | `string[]` | `['path', 'cookie', 'header']` | Ordered list of locale detectors |
|
|
76
|
+
| `detectBrowserLanguage` | `object` | — | Cookie and fallback settings |
|
|
77
|
+
| `autoVitePlugin` | `boolean` | `true` | Auto-register `@fluenti/vite-plugin` |
|
|
78
|
+
| `componentPrefix` | `string` | `''` | Prefix for i18n components |
|
|
79
|
+
| `isr` | `{ enabled, ttl? }` | — | ISR route rules generation |
|
|
80
|
+
| `compat` | `boolean` | `false` | Enable vue-i18n bridge mode |
|
|
81
|
+
|
|
82
|
+
## Routing Strategies
|
|
83
|
+
|
|
84
|
+
| Strategy | Default locale | Other locales | Example |
|
|
85
|
+
|----------|---------------|---------------|---------|
|
|
86
|
+
| `prefix_except_default` | `/about` | `/ja/about` | Most common — clean URLs for default locale |
|
|
87
|
+
| `prefix` | `/en/about` | `/ja/about` | Every locale gets a prefix |
|
|
88
|
+
| `prefix_and_default` | `/about` + `/en/about` | `/ja/about` | Default locale accessible both ways |
|
|
89
|
+
| `no_prefix` | `/about` | `/about` | No URL prefixes — locale set via cookie/header |
|
|
90
|
+
|
|
91
|
+
## Locale Detection
|
|
92
|
+
|
|
93
|
+
When a request arrives, the module runs a detection chain to determine which locale to use. Detectors run in the order specified by `detectOrder`. The first detector to resolve a locale wins.
|
|
94
|
+
|
|
95
|
+
### Detection Flow
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
Request -> detectOrder chain -> fluenti:detect-locale hook -> fallback
|
|
99
|
+
|
|
|
100
|
+
fallbackLocale -> defaultLocale
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Built-in Detectors
|
|
104
|
+
|
|
105
|
+
| Detector | Reads from | Example | Notes |
|
|
106
|
+
|----------|-----------|---------|-------|
|
|
107
|
+
| `path` | URL prefix | `/ja/about` -> `ja` | Most reliable for SEO |
|
|
108
|
+
| `cookie` | Cookie value | `fluenti_locale=ja` | Persists across visits |
|
|
109
|
+
| `header` | `Accept-Language` | `ja,en;q=0.5` -> `ja` | Server-side only, content negotiation |
|
|
110
|
+
| `query` | Query parameter | `?locale=ja` -> `ja` | Useful for previewing |
|
|
111
|
+
|
|
112
|
+
### detectBrowserLanguage
|
|
113
|
+
|
|
114
|
+
Controls cookie persistence and fallback behavior:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
detectBrowserLanguage: {
|
|
118
|
+
useCookie: true, // persist detected locale in a cookie
|
|
119
|
+
cookieKey: 'fluenti_locale', // cookie name (default: 'fluenti_locale')
|
|
120
|
+
fallbackLocale: 'en', // used when no detector resolves
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
When `useCookie` is enabled, the module automatically:
|
|
125
|
+
- Reads the locale from the cookie during detection
|
|
126
|
+
- Writes the cookie whenever the locale changes
|
|
127
|
+
|
|
128
|
+
The `fallbackLocale` is used when no detector in the chain resolves a locale. If not set, `defaultLocale` is used.
|
|
129
|
+
|
|
130
|
+
### Custom Detector Hook
|
|
131
|
+
|
|
132
|
+
Use the `fluenti:detect-locale` Nuxt hook to add custom detection logic. The hook runs after all built-in detectors, but only if no detector has resolved yet.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
// modules/custom-detect.ts
|
|
136
|
+
import { defineNuxtModule, addPlugin, createResolver } from '@nuxt/kit'
|
|
137
|
+
|
|
138
|
+
export default defineNuxtModule({
|
|
139
|
+
setup(_, nuxt) {
|
|
140
|
+
const { resolve } = createResolver(import.meta.url)
|
|
141
|
+
addPlugin({ src: resolve('./runtime/detect-plugin'), order: -1 })
|
|
142
|
+
},
|
|
143
|
+
})
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
// modules/runtime/detect-plugin.ts
|
|
148
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
149
|
+
nuxtApp.hook('fluenti:detect-locale', (ctx) => {
|
|
150
|
+
if (!ctx.isServer) return
|
|
151
|
+
|
|
152
|
+
const event = useRequestEvent()
|
|
153
|
+
const headerLocale = event?.headers?.get('x-user-locale')
|
|
154
|
+
|
|
155
|
+
if (headerLocale && ctx.locales.includes(headerLocale)) {
|
|
156
|
+
ctx.setLocale(headerLocale)
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The `LocaleDetectContext` passed to the hook:
|
|
163
|
+
|
|
164
|
+
| Property | Type | Description |
|
|
165
|
+
|----------|------|-------------|
|
|
166
|
+
| `path` | `string` | The request path |
|
|
167
|
+
| `locales` | `string[]` | Available locale codes |
|
|
168
|
+
| `defaultLocale` | `string` | Default locale |
|
|
169
|
+
| `strategy` | `Strategy` | Routing strategy |
|
|
170
|
+
| `detectedLocale` | `string \| null` | Locale detected so far |
|
|
171
|
+
| `setLocale` | `(locale) => void` | Call to claim a locale and stop the chain |
|
|
172
|
+
| `isServer` | `boolean` | Whether running on the server |
|
|
173
|
+
|
|
174
|
+
## Locale Redirect Middleware
|
|
175
|
+
|
|
176
|
+
When using the `prefix` strategy, a global middleware automatically redirects unprefixed URLs to locale-prefixed ones:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
GET /about -> 302 -> /en/about (detected via cookie/header/fallback)
|
|
180
|
+
GET /ja/about -> no redirect (already has prefix)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
The middleware only activates for the `prefix` strategy. For `prefix_except_default`, unprefixed paths are treated as the default locale.
|
|
184
|
+
|
|
185
|
+
## Composables
|
|
186
|
+
|
|
187
|
+
### useLocalePath()
|
|
188
|
+
|
|
189
|
+
Generate locale-prefixed paths.
|
|
190
|
+
|
|
191
|
+
```vue
|
|
192
|
+
<script setup>
|
|
193
|
+
const localePath = useLocalePath()
|
|
194
|
+
</script>
|
|
195
|
+
|
|
196
|
+
<template>
|
|
197
|
+
<NuxtLink :to="localePath('/about')">About</NuxtLink>
|
|
198
|
+
<NuxtLink :to="localePath('/about', 'ja')">About (JA)</NuxtLink>
|
|
199
|
+
</template>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### useSwitchLocalePath()
|
|
203
|
+
|
|
204
|
+
Get the current page path in a different locale.
|
|
205
|
+
|
|
206
|
+
```vue
|
|
207
|
+
<script setup>
|
|
208
|
+
const switchLocalePath = useSwitchLocalePath()
|
|
209
|
+
</script>
|
|
210
|
+
|
|
211
|
+
<template>
|
|
212
|
+
<!-- If on /ja/about, this returns /about (en is default) -->
|
|
213
|
+
<NuxtLink :to="switchLocalePath('en')">English</NuxtLink>
|
|
214
|
+
<NuxtLink :to="switchLocalePath('ja')">日本語</NuxtLink>
|
|
215
|
+
</template>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### useLocaleHead()
|
|
219
|
+
|
|
220
|
+
Generate SEO-friendly `<head>` metadata — `hreflang` alternate links, `og:locale` meta tags, and `html[lang]`.
|
|
221
|
+
|
|
222
|
+
```vue
|
|
223
|
+
<script setup>
|
|
224
|
+
const head = useLocaleHead({
|
|
225
|
+
addSeoAttributes: true,
|
|
226
|
+
baseUrl: 'https://example.com',
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
useHead(head.value)
|
|
230
|
+
</script>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Generated output:
|
|
234
|
+
|
|
235
|
+
```html
|
|
236
|
+
<html lang="en">
|
|
237
|
+
<head>
|
|
238
|
+
<link rel="alternate" hreflang="en" href="https://example.com/about" />
|
|
239
|
+
<link rel="alternate" hreflang="ja" href="https://example.com/ja/about" />
|
|
240
|
+
<link rel="alternate" hreflang="x-default" href="https://example.com/about" />
|
|
241
|
+
<meta property="og:locale" content="en" />
|
|
242
|
+
<meta property="og:locale:alternate" content="ja" />
|
|
243
|
+
</head>
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
| Option | Type | Default | Description |
|
|
247
|
+
|--------|------|---------|-------------|
|
|
248
|
+
| `addSeoAttributes` | `boolean` | `false` | Generate hreflang and og:locale tags |
|
|
249
|
+
| `baseUrl` | `string` | `''` | Base URL for absolute hreflang links |
|
|
250
|
+
|
|
251
|
+
## Components
|
|
252
|
+
|
|
253
|
+
### NuxtLinkLocale
|
|
254
|
+
|
|
255
|
+
A locale-aware wrapper around `<NuxtLink>` that automatically prefixes paths based on the current locale and routing strategy.
|
|
256
|
+
|
|
257
|
+
```vue
|
|
258
|
+
<template>
|
|
259
|
+
<!-- Uses current locale -->
|
|
260
|
+
<NuxtLinkLocale to="/about">About</NuxtLinkLocale>
|
|
261
|
+
<!-- Renders: <a href="/ja/about">About</a> when locale is 'ja' -->
|
|
262
|
+
|
|
263
|
+
<!-- Override locale with the locale prop -->
|
|
264
|
+
<NuxtLinkLocale to="/about" locale="ja">About (JA)</NuxtLinkLocale>
|
|
265
|
+
<!-- Always renders: <a href="/ja/about">About (JA)</a> -->
|
|
266
|
+
</template>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
| Prop | Type | Default | Description |
|
|
270
|
+
|------|------|---------|-------------|
|
|
271
|
+
| `to` | `string \| { path: string }` | — | Target path (required) |
|
|
272
|
+
| `locale` | `string` | current locale | Override locale for this link |
|
|
273
|
+
|
|
274
|
+
All other `<NuxtLink>` props and attributes are forwarded.
|
|
275
|
+
|
|
276
|
+
## Route Utilities
|
|
277
|
+
|
|
278
|
+
For programmatic use or custom module setup:
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
import { localePath, switchLocalePath, extractLocaleFromPath, extendPages } from '@fluenti/nuxt'
|
|
282
|
+
|
|
283
|
+
// Add locale prefix to a path
|
|
284
|
+
localePath('/about', 'ja', 'en', 'prefix_except_default')
|
|
285
|
+
// -> '/ja/about'
|
|
286
|
+
|
|
287
|
+
// Get current path in another locale
|
|
288
|
+
switchLocalePath('/ja/about', 'en', ['en', 'ja'], 'en', 'prefix_except_default')
|
|
289
|
+
// -> '/about'
|
|
290
|
+
|
|
291
|
+
// Extract locale from a path
|
|
292
|
+
extractLocaleFromPath('/ja/about', ['en', 'ja'])
|
|
293
|
+
// -> { locale: 'ja', pathWithoutLocale: '/about' }
|
|
294
|
+
|
|
295
|
+
// Extend Nuxt pages with locale-prefixed variants
|
|
296
|
+
extendPages(pages, { locales: ['en', 'ja'], defaultLocale: 'en', strategy: 'prefix_except_default' })
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Auto-imported APIs
|
|
300
|
+
|
|
301
|
+
The module auto-imports the following — no `import` statements needed in components:
|
|
302
|
+
|
|
303
|
+
| API | Source |
|
|
304
|
+
|-----|--------|
|
|
305
|
+
| `useI18n()` | `@fluenti/vue` |
|
|
306
|
+
| `useLocalePath()` | `@fluenti/nuxt` |
|
|
307
|
+
| `useSwitchLocalePath()` | `@fluenti/nuxt` |
|
|
308
|
+
| `useLocaleHead()` | `@fluenti/nuxt` |
|
|
309
|
+
| `<NuxtLinkLocale>` | `@fluenti/nuxt` (global component) |
|
|
310
|
+
|
|
311
|
+
## SSR / SSG / SPA
|
|
312
|
+
|
|
313
|
+
The module works in all three Nuxt rendering modes.
|
|
314
|
+
|
|
315
|
+
### SSR (Server-Side Rendering)
|
|
316
|
+
|
|
317
|
+
- Server runs the full detection chain (path, cookie, Accept-Language header)
|
|
318
|
+
- Detected locale is stored in `nuxtApp.payload` for hydration
|
|
319
|
+
- Client reads locale from payload to prevent hydration mismatch
|
|
320
|
+
- Route changes sync locale reactively via `watch(route.path)`
|
|
321
|
+
|
|
322
|
+
### SSG (Static Site Generation)
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
export default defineNuxtConfig({
|
|
326
|
+
nitro: { preset: 'static' },
|
|
327
|
+
fluenti: {
|
|
328
|
+
locales: ['en', 'ja', 'zh'],
|
|
329
|
+
strategy: 'prefix_except_default',
|
|
330
|
+
},
|
|
331
|
+
})
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
- All locale-prefixed routes are pre-rendered automatically (`crawlLinks: true`)
|
|
335
|
+
- Each locale variant is a separate static HTML file
|
|
336
|
+
- Client-side locale switching works via Vue reactivity
|
|
337
|
+
|
|
338
|
+
### SPA (Single Page Application)
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
export default defineNuxtConfig({
|
|
342
|
+
ssr: false,
|
|
343
|
+
fluenti: {
|
|
344
|
+
locales: ['en', 'ja', 'zh'],
|
|
345
|
+
strategy: 'prefix_except_default',
|
|
346
|
+
detectBrowserLanguage: { useCookie: true },
|
|
347
|
+
},
|
|
348
|
+
})
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
- No server-side detection — locale is detected on the client
|
|
352
|
+
- Extracts locale from URL path, then checks cookie, then defaults
|
|
353
|
+
|
|
354
|
+
### ISR (Incremental Static Regeneration)
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
export default defineNuxtConfig({
|
|
358
|
+
fluenti: {
|
|
359
|
+
locales: ['en', 'ja'],
|
|
360
|
+
strategy: 'prefix_except_default',
|
|
361
|
+
isr: { enabled: true, ttl: 3600 },
|
|
362
|
+
},
|
|
363
|
+
})
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The module automatically generates `routeRules` for each locale pattern:
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
// Generated route rules:
|
|
370
|
+
{
|
|
371
|
+
'/**': { isr: 3600 }, // default locale (prefix_except_default)
|
|
372
|
+
'/ja/**': { isr: 3600 }, // Japanese routes
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Cookie Persistence
|
|
377
|
+
|
|
378
|
+
When `detectBrowserLanguage.useCookie` is enabled:
|
|
379
|
+
|
|
380
|
+
1. On locale detection, the cookie value is checked (after path detection)
|
|
381
|
+
2. When the user switches locale (via `setLocale()` or navigation), the cookie is updated automatically
|
|
382
|
+
3. On return visits, the cookie restores the user's preferred locale
|
|
383
|
+
|
|
384
|
+
The cookie is set with `path: '/'` and uses the key from `cookieKey` (default: `fluenti_locale`).
|
|
385
|
+
|
|
386
|
+
## TypeScript
|
|
387
|
+
|
|
388
|
+
All types are exported:
|
|
389
|
+
|
|
390
|
+
```ts
|
|
391
|
+
import type {
|
|
392
|
+
FluentNuxtOptions,
|
|
393
|
+
Strategy,
|
|
394
|
+
FluentNuxtRuntimeConfig,
|
|
395
|
+
DetectBrowserLanguageOptions,
|
|
396
|
+
LocaleDetectContext,
|
|
397
|
+
LocaleDetectorFn,
|
|
398
|
+
BuiltinDetector,
|
|
399
|
+
ISROptions,
|
|
400
|
+
PageRoute,
|
|
401
|
+
LocaleHeadMeta,
|
|
402
|
+
LocaleHeadOptions,
|
|
403
|
+
} from '@fluenti/nuxt'
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
## Documentation
|
|
407
|
+
|
|
408
|
+
- Full docs: https://fluenti.dev
|
|
409
|
+
- llms.txt: Concise summary
|
|
410
|
+
- Source: https://github.com/usefluenti/fluenti
|
|
411
|
+
- License: MIT
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# Migrating to @fluenti/nuxt from @nuxtjs/i18n
|
|
2
|
+
|
|
3
|
+
> Step-by-step guide to migrate a Nuxt 3 app from @nuxtjs/i18n to Fluenti.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Fluenti is a **compile-time** i18n library — translations are compiled to optimized JS at build time. @nuxtjs/i18n wraps vue-i18n with Nuxt-specific routing and detection. Fluenti's Nuxt module provides similar routing capabilities but with zero-overhead compiled messages.
|
|
8
|
+
|
|
9
|
+
Key differences:
|
|
10
|
+
- Compile-time compilation vs runtime message parsing
|
|
11
|
+
- ICU MessageFormat vs vue-i18n syntax
|
|
12
|
+
- PO or JSON catalogs managed by CLI vs JSON locale files
|
|
13
|
+
- Built-in Vite plugin for build-time transforms
|
|
14
|
+
- Same routing strategies (prefix, prefix_except_default, etc.)
|
|
15
|
+
|
|
16
|
+
## Step-by-step Migration
|
|
17
|
+
|
|
18
|
+
### 1. Install Fluenti
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add @fluenti/core @fluenti/vue @fluenti/nuxt
|
|
22
|
+
pnpm add -D @fluenti/cli
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### 2. Update Nuxt config
|
|
26
|
+
|
|
27
|
+
Before (@nuxtjs/i18n):
|
|
28
|
+
```ts
|
|
29
|
+
// nuxt.config.ts
|
|
30
|
+
export default defineNuxtConfig({
|
|
31
|
+
modules: ['@nuxtjs/i18n'],
|
|
32
|
+
i18n: {
|
|
33
|
+
locales: [
|
|
34
|
+
{ code: 'en', file: 'en.json' },
|
|
35
|
+
{ code: 'ja', file: 'ja.json' },
|
|
36
|
+
],
|
|
37
|
+
defaultLocale: 'en',
|
|
38
|
+
langDir: 'locales',
|
|
39
|
+
strategy: 'prefix_except_default',
|
|
40
|
+
detectBrowserLanguage: {
|
|
41
|
+
useCookie: true,
|
|
42
|
+
cookieKey: 'i18n_redirected',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
After (Fluenti):
|
|
49
|
+
```ts
|
|
50
|
+
// nuxt.config.ts
|
|
51
|
+
export default defineNuxtConfig({
|
|
52
|
+
modules: ['@fluenti/nuxt'],
|
|
53
|
+
fluenti: {
|
|
54
|
+
locales: ['en', 'ja'],
|
|
55
|
+
defaultLocale: 'en',
|
|
56
|
+
strategy: 'prefix_except_default',
|
|
57
|
+
detectBrowserLanguage: {
|
|
58
|
+
useCookie: true,
|
|
59
|
+
cookieKey: 'fluenti_locale',
|
|
60
|
+
},
|
|
61
|
+
catalogDir: './locales',
|
|
62
|
+
format: 'po',
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 3. Update composable usage
|
|
68
|
+
|
|
69
|
+
Before (@nuxtjs/i18n):
|
|
70
|
+
```ts
|
|
71
|
+
const { t, locale, setLocale, locales } = useI18n()
|
|
72
|
+
const localePath = useLocalePath()
|
|
73
|
+
const switchLocalePath = useSwitchLocalePath()
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
After (Fluenti):
|
|
77
|
+
```ts
|
|
78
|
+
const { t, locale, setLocale } = useI18n()
|
|
79
|
+
const localePath = useLocalePath()
|
|
80
|
+
const switchLocalePath = useSwitchLocalePath()
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Most composables have the same API. Key differences in `useI18n()`:
|
|
84
|
+
|
|
85
|
+
### 4. Update template usage
|
|
86
|
+
|
|
87
|
+
Before (@nuxtjs/i18n):
|
|
88
|
+
```vue
|
|
89
|
+
<template>
|
|
90
|
+
<NuxtLink :to="localePath('/about')">{{ t('about') }}</NuxtLink>
|
|
91
|
+
<NuxtLink :to="switchLocalePath('ja')">日本語</NuxtLink>
|
|
92
|
+
<i18n-t keypath="welcome" tag="p">
|
|
93
|
+
<template #name><strong>User</strong></template>
|
|
94
|
+
</i18n-t>
|
|
95
|
+
</template>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
After (Fluenti):
|
|
99
|
+
```vue
|
|
100
|
+
<template>
|
|
101
|
+
<NuxtLinkLocale to="/about">{{ t('about') }}</NuxtLinkLocale>
|
|
102
|
+
<NuxtLink :to="switchLocalePath('ja')">日本語</NuxtLink>
|
|
103
|
+
<Trans message="Welcome, {0}{1}{2}">
|
|
104
|
+
<template #0><strong></template>
|
|
105
|
+
<template #1>User</template>
|
|
106
|
+
<template #2></strong></template>
|
|
107
|
+
</Trans>
|
|
108
|
+
<!-- Or simpler with v-t -->
|
|
109
|
+
<p v-t>Welcome</p>
|
|
110
|
+
</template>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 5. Convert translation files
|
|
114
|
+
|
|
115
|
+
@nuxtjs/i18n JSON format:
|
|
116
|
+
```json
|
|
117
|
+
{
|
|
118
|
+
"hello": "Hello, {name}!",
|
|
119
|
+
"items": "no items | one item | {count} items"
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Fluenti PO format:
|
|
124
|
+
```po
|
|
125
|
+
msgid "hello"
|
|
126
|
+
msgstr "Hello, {name}!"
|
|
127
|
+
|
|
128
|
+
msgid "items"
|
|
129
|
+
msgstr "{count, plural, =0 {no items} one {one item} other {{count} items}}"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Use the CLI to manage catalogs:
|
|
133
|
+
```bash
|
|
134
|
+
# Create fluenti.config.ts
|
|
135
|
+
npx fluenti extract # Extract from source
|
|
136
|
+
npx fluenti compile # Compile to JS
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 6. Update SEO/head meta
|
|
140
|
+
|
|
141
|
+
Before (@nuxtjs/i18n):
|
|
142
|
+
```ts
|
|
143
|
+
const head = useLocaleHead({ addSeoAttributes: true })
|
|
144
|
+
useHead({ htmlAttrs: { lang: head.value.htmlAttrs?.lang }, link: head.value.link, meta: head.value.meta })
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
After (Fluenti):
|
|
148
|
+
```ts
|
|
149
|
+
const head = useLocaleHead()
|
|
150
|
+
useHead(head)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 7. Remove old library
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
pnpm remove @nuxtjs/i18n
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## API Mapping Table
|
|
160
|
+
|
|
161
|
+
| @nuxtjs/i18n | @fluenti/nuxt |
|
|
162
|
+
|--------------|---------------|
|
|
163
|
+
| `useI18n()` | `useI18n()` |
|
|
164
|
+
| `useLocalePath()` | `useLocalePath()` |
|
|
165
|
+
| `useSwitchLocalePath()` | `useSwitchLocalePath()` |
|
|
166
|
+
| `useLocaleHead()` | `useLocaleHead()` |
|
|
167
|
+
| `<NuxtLink :to="localePath(...)">` | `<NuxtLinkLocale to="...">` |
|
|
168
|
+
| `$t(key)` | `t(key)` (via useI18n) |
|
|
169
|
+
| `$tc(key, count)` | `t(key, { count })` (ICU plural) |
|
|
170
|
+
| `strategy: 'prefix_except_default'` | `strategy: 'prefix_except_default'` (same) |
|
|
171
|
+
| `strategy: 'prefix'` | `strategy: 'prefix'` (same) |
|
|
172
|
+
| `strategy: 'prefix_and_default'` | `strategy: 'prefix_and_default'` (same) |
|
|
173
|
+
| `strategy: 'no_prefix'` | `strategy: 'no_prefix'` (same) |
|
|
174
|
+
| `detectBrowserLanguage` | `detectBrowserLanguage` (similar config) |
|
|
175
|
+
| `<i18n-t>` component | `<Trans>` component |
|
|
176
|
+
| Lazy loading via `file` in locales | `loadMessages` callback |
|
|
177
|
+
| `langDir` option | `catalogDir` option |
|
|
178
|
+
|
|
179
|
+
## Routing Strategy Compatibility
|
|
180
|
+
|
|
181
|
+
All four routing strategies from @nuxtjs/i18n are supported with the same names:
|
|
182
|
+
- `prefix_except_default` — `/about` for default, `/ja/about` for others
|
|
183
|
+
- `prefix` — `/en/about`, `/ja/about`
|
|
184
|
+
- `prefix_and_default` — both `/about` and `/en/about` work for default
|
|
185
|
+
- `no_prefix` — no locale in URL, detection via cookie/header
|
|
186
|
+
|
|
187
|
+
## Locale Detection
|
|
188
|
+
|
|
189
|
+
@nuxtjs/i18n detection order: cookie → navigator → header
|
|
190
|
+
Fluenti detection chain: path → cookie → header → fallback
|
|
191
|
+
|
|
192
|
+
Both support cookie-based persistence. Configure via `detectBrowserLanguage` option.
|
|
193
|
+
|
|
194
|
+
## Key Behavioral Differences
|
|
195
|
+
|
|
196
|
+
1. **Compile-time** — messages compiled at build time, no runtime parser in bundle
|
|
197
|
+
2. **ICU MessageFormat** — standard plural/select syntax instead of vue-i18n pipe syntax
|
|
198
|
+
3. **CLI workflow** — extract → translate → compile pipeline
|
|
199
|
+
4. **PO file support** — compatible with Poedit, Crowdin, Weblate
|
|
200
|
+
5. **NuxtLinkLocale** — dedicated component instead of wrapping NuxtLink with localePath
|
|
201
|
+
6. **AI translation** — `npx fluenti translate --provider claude` for automated translation
|