@fluenti/vue 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.
Files changed (40) hide show
  1. package/README.md +5 -5
  2. package/dist/components/DateTime.d.ts +1 -1
  3. package/dist/components/DateTime.d.ts.map +1 -1
  4. package/dist/components/NumberFormat.d.ts +1 -1
  5. package/dist/components/NumberFormat.d.ts.map +1 -1
  6. package/dist/components/Plural.d.ts +12 -13
  7. package/dist/components/Plural.d.ts.map +1 -1
  8. package/dist/components/Select.d.ts +12 -13
  9. package/dist/components/Select.d.ts.map +1 -1
  10. package/dist/components/Trans.d.ts +7 -7
  11. package/dist/components/Trans.d.ts.map +1 -1
  12. package/dist/components/rich-text.d.ts +0 -6
  13. package/dist/components/rich-text.d.ts.map +1 -1
  14. package/dist/hooks/__useI18n.d.ts +2 -2
  15. package/dist/hooks/__useI18n.d.ts.map +1 -1
  16. package/dist/index.cjs +1 -1
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.ts +7 -7
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +155 -169
  21. package/dist/index.js.map +1 -1
  22. package/dist/plugin.d.ts +25 -14
  23. package/dist/plugin.d.ts.map +1 -1
  24. package/dist/server.cjs +2 -0
  25. package/dist/server.cjs.map +1 -0
  26. package/dist/server.d.ts +33 -13
  27. package/dist/server.d.ts.map +1 -1
  28. package/dist/server.js +54 -0
  29. package/dist/server.js.map +1 -0
  30. package/dist/use-i18n.d.ts +3 -3
  31. package/dist/use-i18n.d.ts.map +1 -1
  32. package/dist/vite-plugin.cjs +1 -111
  33. package/dist/vite-plugin.cjs.map +1 -1
  34. package/dist/vite-plugin.js +18 -126
  35. package/dist/vite-plugin.js.map +1 -1
  36. package/dist/vue-runtime.d.ts.map +1 -1
  37. package/llms-full.txt +220 -0
  38. package/llms-migration.txt +199 -0
  39. package/llms.txt +82 -0
  40. package/package.json +17 -5
@@ -0,0 +1,199 @@
1
+ # Migrating to @fluenti/vue from vue-i18n
2
+
3
+ > Step-by-step guide to migrate a Vue 3 app from vue-i18n (v9/v10) to Fluenti.
4
+
5
+ ## Overview
6
+
7
+ Fluenti is a **compile-time** i18n library — translations are compiled to optimized JS at build time, resulting in zero runtime overhead and smaller bundles. vue-i18n is a runtime library that parses messages on every render.
8
+
9
+ Key differences:
10
+ - Fluenti uses ICU MessageFormat; vue-i18n uses its own syntax
11
+ - Fluenti requires a Vite plugin for build-time compilation
12
+ - Fluenti catalog files use PO (gettext) or JSON format, managed by the CLI
13
+ - No runtime parser needed — messages become plain strings or template functions
14
+
15
+ ## Gradual Migration with @fluenti/vue-i18n-compat
16
+
17
+ For large projects, use the compatibility bridge to run both libraries side by side:
18
+
19
+ ```bash
20
+ pnpm add @fluenti/vue-i18n-compat @fluenti/core @fluenti/vue
21
+ ```
22
+
23
+ ```ts
24
+ import { createI18n } from 'vue-i18n'
25
+ import { createFluenti } from '@fluenti/vue'
26
+ import { createFluentBridge } from '@fluenti/vue-i18n-compat'
27
+
28
+ const i18n = createI18n({ legacy: false, locale: 'en', messages: { en: legacyMessages } })
29
+ const fluenti = createFluenti({ locale: 'en', fallbackLocale: 'en', messages: { en: newMessages } })
30
+ const bridge = createFluentBridge({ vueI18n: i18n, fluenti, priority: 'fluenti-first' })
31
+
32
+ app.use(bridge) // installs both, syncs locale, falls through on lookups
33
+ ```
34
+
35
+ Then migrate messages one at a time. When done, remove the bridge and use @fluenti/vue directly.
36
+
37
+ ## Step-by-step Migration (Direct)
38
+
39
+ ### 1. Install Fluenti packages
40
+
41
+ ```bash
42
+ pnpm add @fluenti/core @fluenti/vue
43
+ pnpm add -D @fluenti/cli
44
+ ```
45
+
46
+ ### 2. Update Vite config
47
+
48
+ ```ts
49
+ // vite.config.ts
50
+ import vue from '@vitejs/plugin-vue'
51
+ import fluentiVue from '@fluenti/vue/vite-plugin'
52
+
53
+ export default {
54
+ plugins: [vue(), fluentiVue()],
55
+ }
56
+ ```
57
+
58
+ ### 3. Replace plugin setup
59
+
60
+ Before (vue-i18n):
61
+ ```ts
62
+ import { createI18n } from 'vue-i18n'
63
+ const i18n = createI18n({ locale: 'en', messages: { en, ja } })
64
+ app.use(i18n)
65
+ ```
66
+
67
+ After (Fluenti):
68
+ ```ts
69
+ import { createFluenti } from '@fluenti/vue'
70
+ const fluent = createFluenti({ locale: 'en', fallbackLocale: 'en', messages: { en, ja } })
71
+ app.use(fluent)
72
+ ```
73
+
74
+ ### 4. Update composable usage
75
+
76
+ Before (vue-i18n):
77
+ ```ts
78
+ import { useI18n } from 'vue-i18n'
79
+ const { t, locale } = useI18n()
80
+ ```
81
+
82
+ After (Fluenti):
83
+ ```ts
84
+ import { useI18n } from '@fluenti/vue'
85
+ const { t, locale, setLocale } = useI18n()
86
+ ```
87
+
88
+ ### 5. Convert message syntax
89
+
90
+ vue-i18n named interpolation → ICU MessageFormat:
91
+ ```
92
+ # vue-i18n
93
+ "hello": "Hello, {name}!"
94
+
95
+ # Fluenti (same for simple cases)
96
+ "hello": "Hello, {name}!"
97
+ ```
98
+
99
+ vue-i18n pluralization → ICU plural:
100
+ ```
101
+ # vue-i18n (pipe syntax)
102
+ "items": "no items | one item | {count} items"
103
+
104
+ # Fluenti (ICU MessageFormat)
105
+ "items": "{count, plural, =0 {no items} one {one item} other {{count} items}}"
106
+ ```
107
+
108
+ vue-i18n linked messages → not supported (use message functions):
109
+ ```
110
+ # vue-i18n
111
+ "greeting": "@:hello, welcome!"
112
+
113
+ # Fluenti — inline the full message or use code
114
+ "greeting": "Hello, {name}, welcome!"
115
+ ```
116
+
117
+ ### 6. Update template syntax
118
+
119
+ Before (vue-i18n):
120
+ ```vue
121
+ <template>
122
+ <p>{{ $t('hello', { name: 'World' }) }}</p>
123
+ <i18n-t keypath="terms" tag="p">
124
+ <template #link><a href="/terms">terms</a></template>
125
+ </i18n-t>
126
+ </template>
127
+ ```
128
+
129
+ After (Fluenti):
130
+ ```vue
131
+ <template>
132
+ <p>{{ t('hello', { name: 'World' }) }}</p>
133
+ <Trans message="Read the {0}terms{1}">
134
+ <template #0><a href="/terms"></template>
135
+ <template #1></a></template>
136
+ </Trans>
137
+ <!-- Or use v-t directive for simple text -->
138
+ <p v-t>Hello</p>
139
+ </template>
140
+ ```
141
+
142
+ ### 7. Remove vue-i18n
143
+
144
+ ```bash
145
+ pnpm remove vue-i18n
146
+ ```
147
+
148
+ ## API Mapping Table
149
+
150
+ | vue-i18n | Fluenti |
151
+ |----------|---------|
152
+ | `createI18n()` | `createFluenti()` |
153
+ | `useI18n()` | `useI18n()` |
154
+ | `t(key, values)` | `t(key, values)` |
155
+ | `tc(key, count)` | `t(key, { count })` (ICU plural) |
156
+ | `te(key)` | `te(key)` |
157
+ | `tm(key)` | `tm(key)` |
158
+ | `d(value, format)` | `d(value, style)` |
159
+ | `n(value, format)` | `n(value, style)` |
160
+ | `locale.value = 'ja'` | `setLocale('ja')` |
161
+ | `$t()` in template | `t()` in template (via useI18n) |
162
+ | `<i18n-t>` component | `<Trans>` component |
163
+ | `v-t` directive | `v-t` directive (same syntax) |
164
+ | `@:key` linked messages | Not supported — inline messages |
165
+ | Pipe plurals `a \| b \| c` | ICU `{n, plural, ...}` |
166
+ | `numberFormats` option | `numberFormats` option |
167
+ | `datetimeFormats` option | `dateFormats` option |
168
+
169
+ ## Translation File Conversion
170
+
171
+ Use the Fluenti CLI to manage catalogs:
172
+
173
+ ```bash
174
+ # Create config
175
+ cat > fluenti.config.ts << 'EOF'
176
+ export default {
177
+ sourceLocale: 'en',
178
+ locales: ['en', 'ja'],
179
+ catalogDir: './locales',
180
+ format: 'po',
181
+ include: ['./src/**/*.{vue,ts}'],
182
+ compileOutDir: './locales/compiled',
183
+ }
184
+ EOF
185
+
186
+ # Extract messages from source
187
+ npx fluenti extract
188
+
189
+ # Compile catalogs to JS
190
+ npx fluenti compile
191
+ ```
192
+
193
+ ## Key Behavioral Differences
194
+
195
+ 1. **No runtime parser** — messages are compiled at build time, so syntax errors are caught early
196
+ 2. **No lazy locale loading by default** — use `lazyLocaleLoading: true` with a `chunkLoader` for dynamic locale chunks
197
+ 3. **No global `$t`** — use `useI18n()` composable or `v-t` directive
198
+ 4. **ICU MessageFormat** — standard plural/select/number/date formatting, not custom vue-i18n syntax
199
+ 5. **PO file support** — compatible with professional translation tools (Poedit, Crowdin, Weblate)
package/llms.txt ADDED
@@ -0,0 +1,82 @@
1
+ # @fluenti/vue
2
+
3
+ > Vue 3 bindings for Fluenti — compile-time `t`, `v-t`, runtime-capable components, and a `useI18n()` composable.
4
+
5
+ @fluenti/vue provides the Vue-side runtime for Fluenti. The recommended authoring path is:
6
+
7
+ - compile-time: `import { t } from '@fluenti/vue'`
8
+ - runtime / imperative usage: `useI18n()`
9
+ - template authoring: `v-t`, `<Trans>`, `<Plural>`, `<Select>`
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pnpm add @fluenti/core @fluenti/vue @fluenti/vite-plugin
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```ts
20
+ import { createFluenti } from '@fluenti/vue'
21
+
22
+ const fluent = createFluenti({
23
+ locale: 'en',
24
+ fallbackLocale: 'en',
25
+ messages: { en, ja },
26
+ })
27
+
28
+ app.use(fluent)
29
+ ```
30
+
31
+ ## Main Exports
32
+
33
+ - `createFluenti(options)` — Vue plugin factory
34
+ - `useI18n()` — composable returning the full i18n context
35
+ - `t` — compile-time-only authoring API for tagged templates and descriptors
36
+ - `Trans`, `Plural`, `Select`, `DateTime`, `NumberFormat` — runtime-capable components
37
+ - `FluentiTransProps`, `FluentiPluralProps`, `FluentiSelectProps`, `FluentiDateTimeProps`, `FluentiNumberFormatProps` — component prop types
38
+ - `msg` — lazy message descriptor helper
39
+ - `FLUENTI_KEY` — injection key
40
+
41
+ ## Plugin Options
42
+
43
+ | Option | Type | Default | Description |
44
+ |--------|------|---------|-------------|
45
+ | `locale` | `string` | — | Active locale (required) |
46
+ | `messages` | `Record<string, Messages>` | — | Message catalogs (required) |
47
+ | `fallbackLocale` | `string` | — | Fallback locale |
48
+ | `fallbackChain` | `Record<string, string[]>` | — | Locale-specific fallback chains |
49
+ | `dateFormats` | `Record<string, DateTimeFormatOptions \| 'relative'>` | — | Named date presets |
50
+ | `numberFormats` | `Record<string, NumberFormatOptions>` | — | Named number presets |
51
+ | `missing` | `(locale, id) => string \| undefined` | — | Missing handler |
52
+ | `componentPrefix` | `string` | `''` | Prefix for registered components |
53
+ | `lazyLocaleLoading` | `boolean` | `false` | Enable async locale loading |
54
+ | `chunkLoader` | `(locale) => Promise<Messages \| { default: Messages }>` | — | Async loader used with `lazyLocaleLoading` |
55
+
56
+ ## Important Boundaries
57
+
58
+ - `t` imported from `@fluenti/vue` is compile-time only and requires the Fluenti plugin / loader
59
+ - `useI18n().t()` is the full runtime API for lookup and imperative formatting
60
+ - `<Trans>`, `<Plural>`, `<Select>`, `<DateTime>`, and `<NumberFormat>` remain runtime-capable even without the build plugin
61
+
62
+ ## Preferred Usage (compile-time first)
63
+
64
+ 1. `v-t` directive — `<p v-t>Hello {name}</p>` (Vue templates, zero runtime cost)
65
+ 2. t\`\` tagged template — t\`Hello {name}\` (primary compile-time API)
66
+ 3. `<Trans>` / `<Plural>` / `<Select>` — rich text with inline markup
67
+ 4. `msg` tagged template — outside components (route meta, stores)
68
+ 5. `useI18n().t()` — runtime fallback for dynamic keys only
69
+
70
+ ❌ AVOID: `t('some.key')` as the default — this is a legacy i18n pattern.
71
+
72
+ ## Server Subpath: `@fluenti/vue/server`
73
+
74
+ Server-side utilities for SSR:
75
+
76
+ - `createServerI18n(config)` — request-scoped runtime helpers for server rendering
77
+ - Re-exports from `@fluenti/core`: `detectLocale`, `getSSRLocaleScript`, `getHydratedLocale`, `isRTL`, `getDirection`
78
+
79
+ ## Docs
80
+
81
+ - Full docs: https://fluenti.dev
82
+ - Source: https://github.com/usefluenti/fluenti
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluenti/vue",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "Vue 3 compile-time i18n — v-t directive, Trans/Plural/Select components, useI18n composable",
6
6
  "homepage": "https://fluenti.dev",
@@ -41,6 +41,16 @@
41
41
  "default": "./dist/index.cjs"
42
42
  }
43
43
  },
44
+ "./server": {
45
+ "import": {
46
+ "types": "./dist/server.d.ts",
47
+ "default": "./dist/server.js"
48
+ },
49
+ "require": {
50
+ "types": "./dist/server.d.ts",
51
+ "default": "./dist/server.cjs"
52
+ }
53
+ },
44
54
  "./vite-plugin": {
45
55
  "import": {
46
56
  "types": "./dist/vite-plugin.d.ts",
@@ -53,7 +63,8 @@
53
63
  }
54
64
  },
55
65
  "files": [
56
- "dist"
66
+ "dist",
67
+ "llms*.txt"
57
68
  ],
58
69
  "peerDependencies": {
59
70
  "vue": "^3.5",
@@ -65,8 +76,8 @@
65
76
  }
66
77
  },
67
78
  "dependencies": {
68
- "@fluenti/core": "0.2.0",
69
- "@fluenti/vite-plugin": "0.2.0"
79
+ "@fluenti/core": "0.3.0",
80
+ "@fluenti/vite-plugin": "0.3.0"
70
81
  },
71
82
  "devDependencies": {
72
83
  "typescript": "^5.9",
@@ -82,6 +93,7 @@
82
93
  "build": "vite build",
83
94
  "dev": "vite build --watch",
84
95
  "test": "vitest run",
85
- "typecheck": "tsc --noEmit"
96
+ "typecheck": "tsc --noEmit",
97
+ "bench": "vitest bench"
86
98
  }
87
99
  }