@intlayer/docs 5.8.0-canary.0 → 5.8.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/blog/ar/intlayer_with_next-i18next.md +2 -2
- package/blog/ar/next-i18next_vs_next-intl_vs_intlayer.md +96 -219
- package/blog/ar/react-i18next_vs_react-intl_vs_intlayer.md +88 -129
- package/blog/ar/vue-i18n_vs_intlayer.md +268 -0
- package/blog/de/intlayer_with_next-i18next.md +2 -2
- package/blog/de/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/de/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/de/vue-i18n_vs_intlayer.md +268 -0
- package/blog/en/intlayer_with_next-i18next.md +2 -2
- package/blog/en/next-i18next_vs_next-intl_vs_intlayer.md +89 -220
- package/blog/en/react-i18next_vs_react-intl_vs_intlayer.md +85 -123
- package/blog/en/vue-i18n_vs_intlayer.md +268 -0
- package/blog/en-GB/intlayer_with_next-i18next.md +2 -2
- package/blog/en-GB/next-i18next_vs_next-intl_vs_intlayer.md +85 -218
- package/blog/en-GB/react-i18next_vs_react-intl_vs_intlayer.md +80 -130
- package/blog/en-GB/vue-i18n_vs_intlayer.md +258 -0
- package/blog/es/intlayer_with_next-i18next.md +2 -2
- package/blog/es/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/es/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/es/vue-i18n_vs_intlayer.md +268 -0
- package/blog/fr/intlayer_with_next-i18next.md +2 -2
- package/blog/fr/next-i18next_vs_next-intl_vs_intlayer.md +91 -214
- package/blog/fr/react-i18next_vs_react-intl_vs_intlayer.md +86 -127
- package/blog/fr/vue-i18n_vs_intlayer.md +269 -0
- package/blog/hi/intlayer_with_next-i18next.md +2 -2
- package/blog/hi/next-i18next_vs_next-intl_vs_intlayer.md +97 -220
- package/blog/hi/react-i18next_vs_react-intl_vs_intlayer.md +89 -130
- package/blog/hi/vue-i18n_vs_intlayer.md +268 -0
- package/blog/it/intlayer_with_next-i18next.md +2 -2
- package/blog/it/next-i18next_vs_next-intl_vs_intlayer.md +91 -214
- package/blog/it/react-i18next_vs_react-intl_vs_intlayer.md +86 -127
- package/blog/it/vue-i18n_vs_intlayer.md +268 -0
- package/blog/ja/intlayer_with_next-i18next.md +2 -2
- package/blog/ja/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/ja/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/ja/vue-i18n_vs_intlayer.md +268 -0
- package/blog/ko/intlayer_with_next-i18next.md +2 -2
- package/blog/ko/next-i18next_vs_next-intl_vs_intlayer.md +95 -217
- package/blog/ko/react-i18next_vs_react-intl_vs_intlayer.md +89 -130
- package/blog/ko/vue-i18n_vs_intlayer.md +268 -0
- package/blog/pt/intlayer_with_next-i18next.md +2 -2
- package/blog/pt/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/pt/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/pt/vue-i18n_vs_intlayer.md +268 -0
- package/blog/ru/intlayer_with_next-i18next.md +2 -2
- package/blog/ru/next-i18next_vs_next-intl_vs_intlayer.md +94 -217
- package/blog/ru/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/ru/vue-i18n_vs_intlayer.md +268 -0
- package/blog/zh/intlayer_with_next-i18next.md +2 -2
- package/blog/zh/next-i18next_vs_next-intl_vs_intlayer.md +93 -216
- package/blog/zh/react-i18next_vs_react-intl_vs_intlayer.md +87 -128
- package/blog/zh/vue-i18n_vs_intlayer.md +269 -0
- package/dist/cjs/generated/blog.entry.cjs +41 -0
- package/dist/cjs/generated/blog.entry.cjs.map +1 -1
- package/dist/esm/generated/blog.entry.mjs +41 -0
- package/dist/esm/generated/blog.entry.mjs.map +1 -1
- package/dist/types/generated/blog.entry.d.ts +1 -0
- package/dist/types/generated/blog.entry.d.ts.map +1 -1
- package/docs/ar/formatters.md +417 -31
- package/docs/ar/how_works_intlayer.md +2 -4
- package/docs/ar/interest_of_intlayer.md +7 -10
- package/docs/ar/intlayer_CMS.md +2 -3
- package/docs/ar/intlayer_visual_editor.md +2 -3
- package/docs/ar/intlayer_with_tanstack.md +1 -1
- package/docs/ar/introduction.md +4 -4
- package/docs/de/formatters.md +444 -34
- package/docs/de/introduction.md +2 -2
- package/docs/en/dictionary/enumeration.md +2 -2
- package/docs/en/dictionary/function_fetching.md +2 -2
- package/docs/en/dictionary/get_started.md +2 -2
- package/docs/en/dictionary/translation.md +2 -2
- package/docs/en/formatters.md +383 -15
- package/docs/en/how_works_intlayer.md +2 -4
- package/docs/en/interest_of_intlayer.md +40 -29
- package/docs/en/intlayer_CMS.md +2 -3
- package/docs/en/intlayer_visual_editor.md +2 -3
- package/docs/en/intlayer_with_create_react_app.md +2 -2
- package/docs/en/intlayer_with_express.md +2 -2
- package/docs/en/intlayer_with_tanstack.md +1 -1
- package/docs/en/introduction.md +4 -4
- package/docs/en/packages/express-intlayer/index.md +2 -2
- package/docs/en/packages/intlayer/getConfiguration.md +2 -3
- package/docs/en/packages/intlayer/getEnumeration.md +2 -7
- package/docs/en/packages/intlayer/getHTMLTextDir.md +2 -4
- package/docs/en/packages/intlayer/getLocaleLang.md +2 -4
- package/docs/en/packages/intlayer/getLocaleName.md +2 -3
- package/docs/en/packages/intlayer/getLocalizedUrl.md +2 -8
- package/docs/en/packages/intlayer/getMultilingualUrls.md +2 -7
- package/docs/en/packages/intlayer/getPathWithoutLocale.md +2 -3
- package/docs/en/packages/intlayer/getTranslation.md +2 -4
- package/docs/en/packages/intlayer/index.md +2 -2
- package/docs/en/packages/next-intlayer/index.md +2 -2
- package/docs/en/packages/next-intlayer/t.md +2 -2
- package/docs/en/packages/next-intlayer/useDictionary.md +2 -2
- package/docs/en/packages/next-intlayer/useIntlayer.md +2 -2
- package/docs/en/packages/next-intlayer/useLocale.md +2 -2
- package/docs/en/packages/react-intlayer/index.md +2 -2
- package/docs/en/packages/react-intlayer/t.md +2 -2
- package/docs/en/packages/react-intlayer/useI18n.md +2 -2
- package/docs/en/packages/react-intlayer/useIntlayer.md +2 -2
- package/docs/en/packages/react-intlayer/useLocale.md +2 -2
- package/docs/en/packages/react-scripts-intlayer/index.md +2 -2
- package/docs/en/packages/solid-intlayer/index.md +2 -2
- package/docs/en/packages/vite-intlayer/index.md +2 -2
- package/docs/en-GB/formatters.md +402 -16
- package/docs/en-GB/how_works_intlayer.md +2 -4
- package/docs/en-GB/interest_of_intlayer.md +7 -10
- package/docs/en-GB/intlayer_with_tanstack.md +1 -1
- package/docs/en-GB/introduction.md +2 -2
- package/docs/es/formatters.md +438 -28
- package/docs/es/how_works_intlayer.md +2 -4
- package/docs/es/interest_of_intlayer.md +7 -10
- package/docs/es/intlayer_with_tanstack.md +1 -1
- package/docs/es/introduction.md +2 -2
- package/docs/fr/formatters.md +438 -28
- package/docs/fr/how_works_intlayer.md +2 -4
- package/docs/fr/interest_of_intlayer.md +7 -10
- package/docs/fr/intlayer_with_tanstack.md +1 -1
- package/docs/fr/introduction.md +2 -2
- package/docs/hi/formatters.md +430 -39
- package/docs/hi/how_works_intlayer.md +2 -4
- package/docs/hi/interest_of_intlayer.md +7 -10
- package/docs/hi/intlayer_with_tanstack.md +1 -1
- package/docs/hi/introduction.md +2 -2
- package/docs/it/formatters.md +438 -30
- package/docs/it/how_works_intlayer.md +2 -4
- package/docs/it/interest_of_intlayer.md +7 -10
- package/docs/it/intlayer_with_tanstack.md +1 -1
- package/docs/it/introduction.md +2 -2
- package/docs/ja/formatters.md +435 -47
- package/docs/ja/how_works_intlayer.md +2 -4
- package/docs/ja/interest_of_intlayer.md +7 -10
- package/docs/ja/intlayer_with_tanstack.md +1 -1
- package/docs/ja/introduction.md +2 -2
- package/docs/ko/formatters.md +432 -41
- package/docs/ko/how_works_intlayer.md +2 -4
- package/docs/ko/interest_of_intlayer.md +7 -10
- package/docs/ko/intlayer_with_tanstack.md +1 -1
- package/docs/ko/introduction.md +2 -2
- package/docs/pt/formatters.md +416 -30
- package/docs/pt/how_works_intlayer.md +2 -4
- package/docs/pt/intlayer_with_tanstack.md +1 -1
- package/docs/pt/introduction.md +2 -2
- package/docs/ru/autoFill.md +2 -2
- package/docs/ru/configuration.md +1 -40
- package/docs/ru/formatters.md +438 -28
- package/docs/ru/how_works_intlayer.md +5 -7
- package/docs/ru/index.md +1 -1
- package/docs/ru/interest_of_intlayer.md +8 -11
- package/docs/ru/intlayer_CMS.md +7 -8
- package/docs/ru/intlayer_cli.md +4 -7
- package/docs/ru/intlayer_visual_editor.md +5 -6
- package/docs/ru/intlayer_with_angular.md +1 -1
- package/docs/ru/intlayer_with_create_react_app.md +5 -5
- package/docs/ru/intlayer_with_lynx+react.md +1 -1
- package/docs/ru/intlayer_with_nextjs_15.md +3 -3
- package/docs/ru/intlayer_with_nextjs_page_router.md +2 -2
- package/docs/ru/intlayer_with_nuxt.md +1 -1
- package/docs/ru/intlayer_with_react_native+expo.md +2 -2
- package/docs/ru/intlayer_with_tanstack.md +3 -3
- package/docs/ru/intlayer_with_vite+preact.md +3 -3
- package/docs/ru/intlayer_with_vite+react.md +3 -3
- package/docs/ru/intlayer_with_vite+solid.md +1 -1
- package/docs/ru/intlayer_with_vite+svelte.md +1 -1
- package/docs/ru/intlayer_with_vite+vue.md +2 -2
- package/docs/ru/introduction.md +5 -5
- package/docs/ru/locale_mapper.md +1 -1
- package/docs/ru/packages/@intlayer/api/index.md +2 -2
- package/docs/ru/packages/@intlayer/chokidar/index.md +1 -1
- package/docs/ru/packages/@intlayer/cli/index.md +2 -2
- package/docs/ru/packages/@intlayer/config/index.md +2 -2
- package/docs/ru/packages/@intlayer/core/index.md +2 -2
- package/docs/ru/packages/@intlayer/design-system/index.md +2 -2
- package/docs/ru/packages/@intlayer/dictionary-entry/index.md +2 -2
- package/docs/ru/packages/@intlayer/editor/index.md +1 -1
- package/docs/ru/packages/@intlayer/editor-react/index.md +1 -1
- package/docs/ru/packages/@intlayer/webpack/index.md +1 -1
- package/docs/ru/packages/angular-intlayer/index.md +1 -1
- package/docs/ru/packages/express-intlayer/index.md +3 -3
- package/docs/ru/packages/express-intlayer/t.md +1 -1
- package/docs/ru/packages/intlayer/getEnumeration.md +3 -8
- package/docs/ru/packages/intlayer/getTranslation.md +3 -5
- package/docs/ru/packages/intlayer/getTranslationContent.md +1 -3
- package/docs/ru/packages/intlayer/index.md +3 -3
- package/docs/ru/packages/intlayer-cli/index.md +1 -1
- package/docs/ru/packages/intlayer-editor/index.md +2 -2
- package/docs/ru/packages/lynx-intlayer/index.md +1 -1
- package/docs/ru/packages/next-intlayer/index.md +4 -4
- package/docs/ru/packages/next-intlayer/t.md +4 -4
- package/docs/ru/packages/next-intlayer/useLocale.md +3 -3
- package/docs/ru/packages/nuxt-intlayer/index.md +1 -1
- package/docs/ru/packages/preact-intlayer/index.md +1 -1
- package/docs/ru/packages/react-intlayer/index.md +4 -4
- package/docs/ru/packages/react-intlayer/t.md +4 -4
- package/docs/ru/packages/react-native-intlayer/index.md +1 -1
- package/docs/ru/packages/react-scripts-intlayer/index.md +3 -3
- package/docs/ru/packages/solid-intlayer/index.md +3 -3
- package/docs/ru/packages/svelte-intlayer/index.md +1 -1
- package/docs/ru/packages/vite-intlayer/index.md +3 -3
- package/docs/ru/packages/vue-intlayer/index.md +1 -1
- package/docs/ru/per_locale_file.md +1 -1
- package/docs/ru/roadmap.md +3 -5
- package/docs/ru/vs_code_extension.md +1 -1
- package/docs/zh/formatters.md +446 -38
- package/docs/zh/how_works_intlayer.md +2 -4
- package/docs/zh/interest_of_intlayer.md +7 -10
- package/docs/zh/intlayer_with_tanstack.md +1 -1
- package/docs/zh/introduction.md +2 -2
- package/frequent_questions/ar/domain_routing.md +1 -1
- package/frequent_questions/en/domain_routing.md +1 -1
- package/frequent_questions/en-GB/domain_routing.md +1 -1
- package/frequent_questions/es/domain_routing.md +1 -1
- package/frequent_questions/fr/domain_routing.md +1 -1
- package/frequent_questions/hi/domain_routing.md +1 -1
- package/frequent_questions/it/domain_routing.md +1 -1
- package/frequent_questions/ko/domain_routing.md +1 -1
- package/frequent_questions/pt/domain_routing.md +1 -1
- package/frequent_questions/ru/domain_routing.md +1 -1
- package/frequent_questions/ru/get_locale_cookie.md +4 -4
- package/frequent_questions/ru/static_rendering.md +1 -2
- package/frequent_questions/zh/domain_routing.md +1 -1
- package/package.json +7 -7
- package/src/generated/blog.entry.ts +41 -0
package/docs/en/formatters.md
CHANGED
|
@@ -13,6 +13,7 @@ keywords:
|
|
|
13
13
|
- Relative Time
|
|
14
14
|
- Units
|
|
15
15
|
- Compact
|
|
16
|
+
- List
|
|
16
17
|
- Internationalization
|
|
17
18
|
slugs:
|
|
18
19
|
- doc
|
|
@@ -37,6 +38,18 @@ import {
|
|
|
37
38
|
relativeTime,
|
|
38
39
|
units,
|
|
39
40
|
compact,
|
|
41
|
+
list,
|
|
42
|
+
getLocaleName,
|
|
43
|
+
getLocaleLang,
|
|
44
|
+
getLocaleFromPath,
|
|
45
|
+
getPathWithoutLocale,
|
|
46
|
+
getLocalizedUrl,
|
|
47
|
+
getHTMLTextDir,
|
|
48
|
+
getContent,
|
|
49
|
+
getLocalisedContent,
|
|
50
|
+
getTranslation,
|
|
51
|
+
getIntlayer,
|
|
52
|
+
getIntlayerAsync,
|
|
40
53
|
} from "intlayer";
|
|
41
54
|
```
|
|
42
55
|
|
|
@@ -44,7 +57,7 @@ If you are using React, hooks are also available; see `react-intlayer/format`.
|
|
|
44
57
|
|
|
45
58
|
## Cached Intl
|
|
46
59
|
|
|
47
|
-
The exported `Intl` is a thin, cached wrapper around the global `Intl`. It memoizes instances of `NumberFormat`, `DateTimeFormat`, `RelativeTimeFormat`, which avoids rebuilding the same formatter repeatedly.
|
|
60
|
+
The exported `Intl` is a thin, cached wrapper around the global `Intl`. It memoizes instances of `NumberFormat`, `DateTimeFormat`, `RelativeTimeFormat`, `ListFormat`, `DisplayNames`, `Collator`, and `PluralRules`, which avoids rebuilding the same formatter repeatedly.
|
|
48
61
|
|
|
49
62
|
Because formatter construction is relatively expensive, this caching improves performance without changing behavior. The wrapper exposes the same API as the native `Intl`, so usage is identical.
|
|
50
63
|
|
|
@@ -52,18 +65,268 @@ Because formatter construction is relatively expensive, this caching improves pe
|
|
|
52
65
|
|
|
53
66
|
> If `Intl.DisplayNames` is not available in the environment, a single dev-only warning is printed (consider a polyfill).
|
|
54
67
|
|
|
55
|
-
|
|
68
|
+
Examples:
|
|
56
69
|
|
|
57
70
|
```ts
|
|
58
71
|
import { Intl } from "intlayer";
|
|
59
72
|
|
|
73
|
+
// Number formatting
|
|
60
74
|
const numberFormat = new Intl.NumberFormat("en-GB", {
|
|
61
75
|
style: "currency",
|
|
62
76
|
currency: "GBP",
|
|
63
77
|
});
|
|
64
78
|
numberFormat.format(1234.5); // "£1,234.50"
|
|
79
|
+
|
|
80
|
+
// Display names for languages, regions, etc.
|
|
81
|
+
const displayNames = new Intl.DisplayNames("fr", { type: "language" });
|
|
82
|
+
displayNames.of("en"); // "anglais"
|
|
83
|
+
|
|
84
|
+
// Collation for sorting
|
|
85
|
+
const collator = new Intl.Collator("fr", { sensitivity: "base" });
|
|
86
|
+
collator.compare("é", "e"); // 0 (equal)
|
|
87
|
+
|
|
88
|
+
// Plural rules
|
|
89
|
+
const pluralRules = new Intl.PluralRules("fr");
|
|
90
|
+
pluralRules.select(1); // "one"
|
|
91
|
+
pluralRules.select(2); // "other"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Additional Intl Utilities
|
|
95
|
+
|
|
96
|
+
Beyond the formatter helpers, you can also use the cached Intl wrapper directly for other Intl features:
|
|
97
|
+
|
|
98
|
+
### `Intl.DisplayNames`
|
|
99
|
+
|
|
100
|
+
For localized names of languages, regions, currencies, and scripts:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { Intl } from "intlayer";
|
|
104
|
+
|
|
105
|
+
const languageNames = new Intl.DisplayNames("en", { type: "language" });
|
|
106
|
+
languageNames.of("fr"); // "French"
|
|
107
|
+
|
|
108
|
+
const regionNames = new Intl.DisplayNames("fr", { type: "region" });
|
|
109
|
+
regionNames.of("US"); // "États-Unis"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### `Intl.Collator`
|
|
113
|
+
|
|
114
|
+
For locale-aware string comparison and sorting:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
import { Intl } from "intlayer";
|
|
118
|
+
|
|
119
|
+
const collator = new Intl.Collator("de", {
|
|
120
|
+
sensitivity: "base",
|
|
121
|
+
numeric: true,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const words = ["äpfel", "zebra", "100", "20"];
|
|
125
|
+
words.sort(collator.compare); // ["20", "100", "äpfel", "zebra"]
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### `Intl.PluralRules`
|
|
129
|
+
|
|
130
|
+
For determining plural forms in different locales:
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { Intl } from "intlayer";
|
|
134
|
+
|
|
135
|
+
const pluralRules = new Intl.PluralRules("ar");
|
|
136
|
+
pluralRules.select(0); // "zero"
|
|
137
|
+
pluralRules.select(1); // "one"
|
|
138
|
+
pluralRules.select(2); // "two"
|
|
139
|
+
pluralRules.select(3); // "few"
|
|
140
|
+
pluralRules.select(11); // "many"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Locale Utilities
|
|
144
|
+
|
|
145
|
+
### `getLocaleName(displayLocale, targetLocale?)`
|
|
146
|
+
|
|
147
|
+
Gets the localized name of a locale in another locale:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
import { getLocaleName } from "intlayer";
|
|
151
|
+
|
|
152
|
+
getLocaleName("fr", "en"); // "French"
|
|
153
|
+
getLocaleName("en", "fr"); // "anglais"
|
|
154
|
+
getLocaleName("de", "es"); // "alemán"
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
- **displayLocale**: The locale to get the name for
|
|
158
|
+
- **targetLocale**: The locale to display the name in (defaults to displayLocale)
|
|
159
|
+
|
|
160
|
+
### `getLocaleLang(locale?)`
|
|
161
|
+
|
|
162
|
+
Extracts the language code from a locale string:
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
import { getLocaleLang } from "intlayer";
|
|
166
|
+
|
|
167
|
+
getLocaleLang("en-US"); // "en"
|
|
168
|
+
getLocaleLang("fr-CA"); // "fr"
|
|
169
|
+
getLocaleLang("de"); // "de"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
- **locale**: The locale to extract the language from (defaults to current locale)
|
|
173
|
+
|
|
174
|
+
### `getLocaleFromPath(inputUrl)`
|
|
175
|
+
|
|
176
|
+
Extracts the locale segment from a URL or pathname:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { getLocaleFromPath } from "intlayer";
|
|
180
|
+
|
|
181
|
+
getLocaleFromPath("/en/dashboard"); // "en"
|
|
182
|
+
getLocaleFromPath("/fr/dashboard"); // "fr"
|
|
183
|
+
getLocaleFromPath("/dashboard"); // "en" (default locale)
|
|
184
|
+
getLocaleFromPath("https://example.com/es/about"); // "es"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
- **inputUrl**: The complete URL string or pathname to process
|
|
188
|
+
- **returns**: The detected locale or default locale if no locale is found
|
|
189
|
+
|
|
190
|
+
### `getPathWithoutLocale(inputUrl, locales?)`
|
|
191
|
+
|
|
192
|
+
Removes the locale segment from a URL or pathname:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import { getPathWithoutLocale } from "intlayer";
|
|
196
|
+
|
|
197
|
+
getPathWithoutLocale("/en/dashboard"); // "/dashboard"
|
|
198
|
+
getPathWithoutLocale("/fr/dashboard"); // "/dashboard"
|
|
199
|
+
getPathWithoutLocale("https://example.com/en/about"); // "https://example.com/about"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
- **inputUrl**: The complete URL string or pathname to process
|
|
203
|
+
- **locales**: Optional array of supported locales (defaults to configured locales)
|
|
204
|
+
- **returns**: The URL without the locale segment
|
|
205
|
+
|
|
206
|
+
### `getLocalizedUrl(url, currentLocale, locales?, defaultLocale?, prefixDefault?)`
|
|
207
|
+
|
|
208
|
+
Generates a localized URL for the current locale:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
import { getLocalizedUrl } from "intlayer";
|
|
212
|
+
|
|
213
|
+
getLocalizedUrl("/about", "fr", ["en", "fr"], "en", false); // "/fr/about"
|
|
214
|
+
getLocalizedUrl("/about", "en", ["en", "fr"], "en", false); // "/about"
|
|
215
|
+
getLocalizedUrl("https://example.com/about", "fr", ["en", "fr"], "en", true); // "https://example.com/fr/about"
|
|
65
216
|
```
|
|
66
217
|
|
|
218
|
+
- **url**: The original URL to localize
|
|
219
|
+
- **currentLocale**: The current locale
|
|
220
|
+
- **locales**: Optional array of supported locales (defaults to configured locales)
|
|
221
|
+
- **defaultLocale**: Optional default locale (defaults to configured default locale)
|
|
222
|
+
- **prefixDefault**: Whether to prefix the default locale (defaults to configured value)
|
|
223
|
+
|
|
224
|
+
### `getHTMLTextDir(locale?)`
|
|
225
|
+
|
|
226
|
+
Returns the text direction for a locale:
|
|
227
|
+
|
|
228
|
+
```ts
|
|
229
|
+
import { getHTMLTextDir } from "intlayer";
|
|
230
|
+
|
|
231
|
+
getHTMLTextDir("en-US"); // "ltr"
|
|
232
|
+
getHTMLTextDir("ar"); // "rtl"
|
|
233
|
+
getHTMLTextDir("he"); // "rtl"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
- **locale**: The locale to get the text direction for (defaults to current locale)
|
|
237
|
+
- **returns**: `"ltr"`, `"rtl"`, or `"auto"`
|
|
238
|
+
|
|
239
|
+
## Content Handling Utilities
|
|
240
|
+
|
|
241
|
+
### `getContent(node, nodeProps, locale?)`
|
|
242
|
+
|
|
243
|
+
Transforms a content node with all available plugins (translation, enumeration, insertion, etc.):
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
import { getContent } from "intlayer";
|
|
247
|
+
|
|
248
|
+
const content = getContent(
|
|
249
|
+
contentNode,
|
|
250
|
+
{ dictionaryKey: "common", dictionaryPath: "/path/to/dict" },
|
|
251
|
+
"fr"
|
|
252
|
+
);
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
- **node**: The content node to transform
|
|
256
|
+
- **nodeProps**: Properties for the transformation context
|
|
257
|
+
- **locale**: Optional locale (defaults to configured default locale)
|
|
258
|
+
|
|
259
|
+
### `getLocalisedContent(node, locale, nodeProps, fallback?)`
|
|
260
|
+
|
|
261
|
+
Transforms a content node with only the translation plugin:
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
import { getLocalisedContent } from "intlayer";
|
|
265
|
+
|
|
266
|
+
const content = getLocalisedContent(
|
|
267
|
+
contentNode,
|
|
268
|
+
"fr",
|
|
269
|
+
{ dictionaryKey: "common" },
|
|
270
|
+
true // fallback to default locale if translation missing
|
|
271
|
+
);
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
- **node**: The content node to transform
|
|
275
|
+
- **locale**: The locale to use for translation
|
|
276
|
+
- **nodeProps**: Properties for the transformation context
|
|
277
|
+
- **fallback**: Whether to fallback to default locale (defaults to false)
|
|
278
|
+
|
|
279
|
+
### `getTranslation(languageContent, locale?, fallback?)`
|
|
280
|
+
|
|
281
|
+
Extracts content for a specific locale from a language content object:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { getTranslation } from "intlayer";
|
|
285
|
+
|
|
286
|
+
const content = getTranslation(
|
|
287
|
+
{
|
|
288
|
+
en: "Hello",
|
|
289
|
+
fr: "Bonjour",
|
|
290
|
+
de: "Hallo",
|
|
291
|
+
},
|
|
292
|
+
"fr",
|
|
293
|
+
true
|
|
294
|
+
); // "Bonjour"
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
- **languageContent**: Object mapping locales to content
|
|
298
|
+
- **locale**: Target locale (defaults to configured default locale)
|
|
299
|
+
- **fallback**: Whether to fallback to default locale (defaults to true)
|
|
300
|
+
|
|
301
|
+
### `getIntlayer(dictionaryKey, locale?, plugins?)`
|
|
302
|
+
|
|
303
|
+
Retrieves and transforms content from a dictionary by key:
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
import { getIntlayer } from "intlayer";
|
|
307
|
+
|
|
308
|
+
const content = getIntlayer("common", "fr");
|
|
309
|
+
const nestedContent = getIntlayer("common", "fr", customPlugins);
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
- **dictionaryKey**: The key of the dictionary to retrieve
|
|
313
|
+
- **locale**: Optional locale (defaults to configured default locale)
|
|
314
|
+
- **plugins**: Optional array of custom transformation plugins
|
|
315
|
+
|
|
316
|
+
### `getIntlayerAsync(dictionaryKey, locale?, plugins?)`
|
|
317
|
+
|
|
318
|
+
Asynchronously retrieves content from a distant dictionary:
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
import { getIntlayerAsync } from "intlayer";
|
|
322
|
+
|
|
323
|
+
const content = await getIntlayerAsync("common", "fr");
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
- **dictionaryKey**: The key of the dictionary to retrieve
|
|
327
|
+
- **locale**: Optional locale (defaults to configured default locale)
|
|
328
|
+
- **plugins**: Optional array of custom transformation plugins
|
|
329
|
+
|
|
67
330
|
## Formatters
|
|
68
331
|
|
|
69
332
|
All helpers below are exported from `intlayer`.
|
|
@@ -81,7 +344,7 @@ Examples:
|
|
|
81
344
|
import { number } from "intlayer";
|
|
82
345
|
|
|
83
346
|
number(123456.789); // "123,456.789" (in en-US)
|
|
84
|
-
number("1000000", { locale: "fr" }); // "1
|
|
347
|
+
number("1000000", { locale: "fr" }); // "1 000 000"
|
|
85
348
|
number(1234.5, { minimumFractionDigits: 2 }); // "1,234.50"
|
|
86
349
|
```
|
|
87
350
|
|
|
@@ -118,7 +381,7 @@ Examples:
|
|
|
118
381
|
import { currency } from "intlayer";
|
|
119
382
|
|
|
120
383
|
currency(1234.5, { currency: "EUR" }); // "€1,234.50"
|
|
121
|
-
currency("5000", { locale: "fr", currency: "CAD", currencyDisplay: "code" }); // "5
|
|
384
|
+
currency("5000", { locale: "fr", currency: "CAD", currencyDisplay: "code" }); // "5 000,00 CAD"
|
|
122
385
|
```
|
|
123
386
|
|
|
124
387
|
### `date(date, optionsOrPreset?)`
|
|
@@ -195,6 +458,25 @@ compact(1200); // "1.2K"
|
|
|
195
458
|
compact("1000000", { locale: "fr", compactDisplay: "long" }); // "1 million"
|
|
196
459
|
```
|
|
197
460
|
|
|
461
|
+
### `list(values, options?)`
|
|
462
|
+
|
|
463
|
+
Formats an array of values into a localized list string using `Intl.ListFormat`.
|
|
464
|
+
|
|
465
|
+
- **values**: `(string | number)[]`
|
|
466
|
+
- **options**: `Intl.ListFormatOptions & { locale?: LocalesValues }`
|
|
467
|
+
- Common fields: `type` (`"conjunction" | "disjunction" | "unit"`), `style` (`"long" | "short" | "narrow"`)
|
|
468
|
+
- Defaults: `type: 'conjunction'`, `style: 'long'`
|
|
469
|
+
|
|
470
|
+
Examples:
|
|
471
|
+
|
|
472
|
+
```ts
|
|
473
|
+
import { list } from "intlayer";
|
|
474
|
+
|
|
475
|
+
list(["apple", "banana", "orange"]); // "apple, banana, and orange"
|
|
476
|
+
list(["red", "green", "blue"], { locale: "fr", type: "disjunction" }); // "rouge, vert ou bleu"
|
|
477
|
+
list([1, 2, 3], { type: "unit" }); // "1, 2, 3"
|
|
478
|
+
```
|
|
479
|
+
|
|
198
480
|
## Notes
|
|
199
481
|
|
|
200
482
|
- All helpers accept `string` inputs; they are internally coerced to numbers or dates.
|
|
@@ -209,25 +491,98 @@ Examples:
|
|
|
209
491
|
|
|
210
492
|
```ts
|
|
211
493
|
// App code (recommended)
|
|
212
|
-
import {
|
|
494
|
+
import {
|
|
495
|
+
number,
|
|
496
|
+
currency,
|
|
497
|
+
date,
|
|
498
|
+
relativeTime,
|
|
499
|
+
units,
|
|
500
|
+
compact,
|
|
501
|
+
list,
|
|
502
|
+
Intl,
|
|
503
|
+
getLocaleName,
|
|
504
|
+
getLocaleLang,
|
|
505
|
+
getLocaleFromPath,
|
|
506
|
+
getPathWithoutLocale,
|
|
507
|
+
getLocalizedUrl,
|
|
508
|
+
getHTMLTextDir,
|
|
509
|
+
getContent,
|
|
510
|
+
getLocalisedContent,
|
|
511
|
+
getTranslation,
|
|
512
|
+
getIntlayer,
|
|
513
|
+
getIntlayerAsync,
|
|
514
|
+
} from "intlayer";
|
|
213
515
|
```
|
|
214
516
|
|
|
215
517
|
### React
|
|
216
518
|
|
|
217
519
|
Client components:
|
|
218
520
|
|
|
219
|
-
```
|
|
220
|
-
import {
|
|
521
|
+
```tsx
|
|
522
|
+
import {
|
|
523
|
+
useNumber,
|
|
524
|
+
useCurrency,
|
|
525
|
+
useDate,
|
|
526
|
+
usePercentage,
|
|
527
|
+
useCompact,
|
|
528
|
+
useList,
|
|
529
|
+
useRelativeTime,
|
|
530
|
+
useUnit,
|
|
531
|
+
} from "react-intlayer/format";
|
|
532
|
+
// or in Preact apps
|
|
533
|
+
// "preact-intlayer/format";
|
|
221
534
|
// or in Next.js apps
|
|
222
|
-
|
|
535
|
+
// "next-intlayer/client/format";
|
|
536
|
+
|
|
537
|
+
const MyComponent = () => {
|
|
538
|
+
const number = useNumber();
|
|
539
|
+
const currency = useCurrency();
|
|
540
|
+
const date = useDate();
|
|
541
|
+
const percentage = usePercentage();
|
|
542
|
+
const compact = useCompact();
|
|
543
|
+
const list = useList();
|
|
544
|
+
const relativeTime = useRelativeTime();
|
|
545
|
+
const unit = useUnit();
|
|
546
|
+
|
|
547
|
+
return (
|
|
548
|
+
<div>
|
|
549
|
+
<p>{number(123456.789)}</p>
|
|
550
|
+
<p>{currency(1234.5, { currency: "EUR" })}</p>
|
|
551
|
+
<p>{date(new Date(), "short")}</p>
|
|
552
|
+
<p>{percentage(0.25)}</p>
|
|
553
|
+
<p>{compact(1200)}</p>
|
|
554
|
+
<p>{list(["apple", "banana", "orange"])}</p>
|
|
555
|
+
<p>{relativeTime(new Date(), new Date() + 1000)}</p>
|
|
556
|
+
<p>{unit(123456.789, { unit: "kilometer" })}</p>
|
|
557
|
+
</div>
|
|
558
|
+
);
|
|
559
|
+
};
|
|
223
560
|
```
|
|
224
561
|
|
|
225
562
|
Server components (or React Server runtime):
|
|
226
563
|
|
|
227
564
|
```ts
|
|
228
|
-
import {
|
|
565
|
+
import {
|
|
566
|
+
useNumber,
|
|
567
|
+
useCurrency,
|
|
568
|
+
useDate,
|
|
569
|
+
usePercentage,
|
|
570
|
+
useCompact,
|
|
571
|
+
useList,
|
|
572
|
+
useRelativeTime,
|
|
573
|
+
useUnit,
|
|
574
|
+
} from "react-intlayer/server/format";
|
|
229
575
|
// or in Next.js apps
|
|
230
|
-
import {
|
|
576
|
+
import {
|
|
577
|
+
useNumber,
|
|
578
|
+
useCurrency,
|
|
579
|
+
useDate,
|
|
580
|
+
usePercentage,
|
|
581
|
+
useCompact,
|
|
582
|
+
useList,
|
|
583
|
+
useRelativeTime,
|
|
584
|
+
useUnit,
|
|
585
|
+
} from "next-intlayer/server/format";
|
|
231
586
|
```
|
|
232
587
|
|
|
233
588
|
> That hooks will consider the locale from the `IntlayerProvider` or `IntlayerServerProvider`
|
|
@@ -237,14 +592,27 @@ import { useNumber, useCurrency, useDate } from "next-intlayer/server/format";
|
|
|
237
592
|
Client components:
|
|
238
593
|
|
|
239
594
|
```ts
|
|
240
|
-
import {
|
|
595
|
+
import {
|
|
596
|
+
useNumber,
|
|
597
|
+
useCurrency,
|
|
598
|
+
useDate,
|
|
599
|
+
usePercentage,
|
|
600
|
+
useCompact,
|
|
601
|
+
useList,
|
|
602
|
+
useRelativeTime,
|
|
603
|
+
useUnit,
|
|
604
|
+
} from "vue-intlayer/format";
|
|
241
605
|
```
|
|
242
606
|
|
|
243
607
|
> That composables will consider the locale from the injected `IntlayerProvider`
|
|
244
608
|
|
|
245
609
|
## Doc History
|
|
246
610
|
|
|
247
|
-
| Version | Date | Changes
|
|
248
|
-
| ------- | ---------- |
|
|
249
|
-
| 5.8.0 | 2025-08-20 | Add vue formatters
|
|
250
|
-
| 5.8.0 | 2025-08-18 | Add formatters documentation
|
|
611
|
+
| Version | Date | Changes |
|
|
612
|
+
| ------- | ---------- | ------------------------------------------------------------------------------ |
|
|
613
|
+
| 5.8.0 | 2025-08-20 | Add vue formatters |
|
|
614
|
+
| 5.8.0 | 2025-08-18 | Add formatters documentation |
|
|
615
|
+
| 5.8.0 | 2025-08-20 | Add list formatter documentation |
|
|
616
|
+
| 5.8.0 | 2025-08-20 | Add additional Intl utilities (DisplayNames, Collator, PluralRules) |
|
|
617
|
+
| 5.8.0 | 2025-08-20 | Add locale utilities (getLocaleName, getLocaleLang, getLocaleFromPath, etc.) |
|
|
618
|
+
| 5.8.0 | 2025-08-20 | Add content handling utilities (getContent, getTranslation, getIntlayer, etc.) |
|
|
@@ -25,8 +25,8 @@ The main idea behind Intlayer is to adopt a per-component content management. So
|
|
|
25
25
|
.
|
|
26
26
|
└── Components
|
|
27
27
|
└── MyComponent
|
|
28
|
-
├── index.content.
|
|
29
|
-
└── index.
|
|
28
|
+
├── index.content.ts
|
|
29
|
+
└── index.tsx
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
To do that, the role of Intlayer is to find all your `content declaration files`, in all different formats present in your project, and then it will generate the `dictionaries` from them.
|
|
@@ -45,12 +45,10 @@ The build step can be done in three ways:
|
|
|
45
45
|
- using the app plugins such as [`vite-intlayer` package](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/packages/vite-intlayer/index.md), or their equivalents for [Next.js](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/packages/next-intlayer/index.md). When you use one of those plugins, Intlayer will automatically build your dictionaries when you start (dev) or build (prod) your application.
|
|
46
46
|
|
|
47
47
|
1. Declaration of content files
|
|
48
|
-
|
|
49
48
|
- Content files can be defined in various formats, such as TypeScript, ECMAScript, CommonJS, or JSON.
|
|
50
49
|
- Content files can be defined everywhere in the project, which allows for better maintenance and scalability. It is important to respect the file extension conventions for content files. This extension is by default `*.content.{js|cjs|mjs|ts|tsx|json}`, but it can be modified in the [configuration file](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md).
|
|
51
50
|
|
|
52
51
|
2. Generation of `dictionaries`
|
|
53
|
-
|
|
54
52
|
- Dictionaries are generated from content files. By default, Intlayer dictionaries are generated in the `.intlayer/dictionaries` directory of the project.
|
|
55
53
|
- Those dictionaries are generated in different formats to match all needs and optimize the performance of the application.
|
|
56
54
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
createdAt: 2024-08-14
|
|
3
|
-
updatedAt: 2025-08-
|
|
3
|
+
updatedAt: 2025-08-23
|
|
4
4
|
title: Interest of Intlayer
|
|
5
5
|
description: Discover the benefits and advantages of using Intlayer in your projects. Understand why Intlayer stands out among other frameworks.
|
|
6
6
|
keywords:
|
|
@@ -197,23 +197,23 @@ This approach allows you to:
|
|
|
197
197
|
- `.content.{{ts|mjs|cjs|json}}` files can be created using a VSCode extension
|
|
198
198
|
- Autocompletion AI tools in your IDE (such as GitHub Copilot) can help you declare your content, reducing copy/paste
|
|
199
199
|
|
|
200
|
-
2. **
|
|
200
|
+
2. **Clean your codebase**
|
|
201
|
+
- Reduce the complexity
|
|
202
|
+
- Increase the maintainability
|
|
201
203
|
|
|
202
|
-
3. **
|
|
203
|
-
|
|
204
|
-
4. **Duplicate your components and their related content more easily (Example: login/register components, etc.)**
|
|
204
|
+
3. **Duplicate your components and their related content more easily (Example: login/register components, etc.)**
|
|
205
205
|
- By limiting the risk of impacting other components' content
|
|
206
206
|
- By copy/pasting your content from one application to another without external dependencies
|
|
207
207
|
|
|
208
|
-
|
|
209
|
-
- If you don't use a component,
|
|
208
|
+
4. **Avoid polluting your codebase with unused keys/values for unused components**
|
|
209
|
+
- If you don't use a component, Intlayer will not import its related content
|
|
210
210
|
- If you delete a component, you'll more easily remember to remove its related content as it will be present in the same folder
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
5. **Reduce reasoning cost for AI agents to declare your multilingual content**
|
|
213
213
|
- The AI agent won't have to scan your entire codebase to know where to implement your content
|
|
214
214
|
- Translations can easily be done by autocompletion AI tools in your IDE (such as GitHub Copilot)
|
|
215
215
|
|
|
216
|
-
|
|
216
|
+
6. **Optimize loading performance**
|
|
217
217
|
- If a component is lazy-loaded, its related content will be loaded at the same time
|
|
218
218
|
|
|
219
219
|
## Additional features of Intlayer
|
|
@@ -240,26 +240,37 @@ This approach allows you to:
|
|
|
240
240
|
|
|
241
241
|
## Comparison of Intlayer with other solutions
|
|
242
242
|
|
|
243
|
-
| Feature |
|
|
244
|
-
| --------------------------------------------- |
|
|
245
|
-
| **Translations Near Components** | Yes, content collocated with each component | No
|
|
246
|
-
| **TypeScript Integration** | Advanced, auto-generated strict types | Basic; extra config for safety
|
|
247
|
-
| **Missing Translation Detection** |
|
|
248
|
-
| **Rich Content (JSX/Markdown/components)** | Direct support
|
|
249
|
-
| **AI-powered Translation** | Yes, supports multiple AI providers. Usable using your own API keys. Considers the context of your application and content scope | No
|
|
250
|
-
| **Visual Editor** | Yes, local Visual Editor + optional CMS; can externalize codebase content; embeddable | No / available via external localization platforms
|
|
251
|
-
| **Localized Routing** |
|
|
252
|
-
| **Dynamic Route Generation** | Yes | Plugin/ecosystem or manual setup
|
|
253
|
-
| **Pluralization** | Enumeration-based patterns
|
|
254
|
-
| **Formatting (dates, numbers, currencies)** | Optimized formatters (Intl under the hood) | Via plugins or custom Intl usage
|
|
255
|
-
| **Content Format** | .tsx, .ts, .js, .json, .md, .txt
|
|
256
|
-
| **ICU support** | WIP
|
|
257
|
-
| **SEO Helpers (hreflang, sitemap)** | Built-in tools: helpers for sitemap,
|
|
258
|
-
| **Ecosystem / Community** | Smaller but growing fast and reactive | Largest and
|
|
259
|
-
| **Server-side Rendering & Server Components** | Yes, streamlined for SSR / React Server Components | Supported
|
|
260
|
-
| **Tree-shaking (load only used content)** | Yes, per-component at build time via Babel/SWC plugins | Usually loads all (can be improved with namespaces/code-splitting)
|
|
261
|
-
| **Lazy loading** | Yes, per-locale/per-
|
|
262
|
-
| **
|
|
243
|
+
| Feature | `intlayer` | `react-i18next` | `react-intl` (FormatJS) | `lingui` | `next-intl` | `next-i18next` | `vue-i18n` |
|
|
244
|
+
| --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
|
|
245
|
+
| **Translations Near Components** | ✅ Yes, content collocated with each component | ❌ No | ❌ No | ❌ No | ❌ No | ❌ No | ✅ Yes - using `Single File Components` (SFCs) |
|
|
246
|
+
| **TypeScript Integration** | ✅ Advanced, auto-generated strict types | ⚠️ Basic; extra config for safety | ✅ Good, but less strict | ⚠️ Typings, needs config | ✅ Good | ⚠️ Basic | ✅ Good (types available; key-safety needs setup) |
|
|
247
|
+
| **Missing Translation Detection** | ✅ TypeScript error hightlight and build-time error/warning | ⚠️ Mostly fallback strings at runtime | ⚠️ Fallback strings | ⚠️ Needs extra config | ⚠️ Runtime fallback | ⚠️ Runtime fallback | ⚠️ Runtime fallback/warnings (configurable) |
|
|
248
|
+
| **Rich Content (JSX/Markdown/components)** | ✅ Direct support | ⚠️ Limited / interpolation only | ⚠️ ICU syntax, not real JSX | ⚠️ Limited | ❌ Not designed for rich nodes | ⚠️ Limited | ⚠️ Limited (components via `<i18n-t>`, Markdown via plugins) |
|
|
249
|
+
| **AI-powered Translation** | ✅ Yes, supports multiple AI providers. Usable using your own API keys. Considers the context of your application and content scope | ❌ No | ❌ No | ❌ No | ❌ No | ❌ No | ❌ No |
|
|
250
|
+
| **Visual Editor** | ✅ Yes, local Visual Editor + optional CMS; can externalize codebase content; embeddable | ❌ No / available via external localization platforms | ❌ No / available via external localization platforms | ❌ No / available via external localization platforms | ❌ No / available via external localization platforms | ❌ No / available via external localization platforms | ❌ No / available via external localization platforms |
|
|
251
|
+
| **Localized Routing** | ✅ Yes, supports localized paths out of the box (works with Next.js & Vite) | ⚠️ No built-in, requires plugins (e.g. `next-i18next`) or custom router config | ❌ No, only message formatting, routing must be manual | ⚠️ No built-in, requires plugins or manual config | ✅ Built-in, App Router supports `[locale]` segment | ✅ Built-in | ✅ Built-in |
|
|
252
|
+
| **Dynamic Route Generation** | ✅ Yes | ⚠️ Plugin/ecosystem or manual setup | ❌ Not provided | ⚠️ Plugin/manual | ✅ Yes | ✅ Yes | ❌ Not provided (Nuxt i18n provides) |
|
|
253
|
+
| **Pluralization** | ✅ Enumeration-based patterns | ✅ Configurable (plugins like i18next-icu) | ✅ (ICU) | ✅ (ICU/messageformat) | ✅ Good | ✅ Good | ✅ Built-in plural rules |
|
|
254
|
+
| **Formatting (dates, numbers, currencies)** | ✅ Optimized formatters (Intl under the hood) | ⚠️ Via plugins or custom Intl usage | ✅ ICU formatters | ✅ ICU/CLI helpers | ✅ Good (Intl helpers) | ✅ Good (Intl helpers) | ✅ Built-in date/number formatters (Intl) |
|
|
255
|
+
| **Content Format** | ✅ .tsx, .ts, .js, .json, .md, .txt, (.yaml WIP) | ⚠️ .json | ✅ .json, .js | ⚠️ .po, .json | ✅ .json, .js, .ts | ⚠️ .json | ✅ .json, .js |
|
|
256
|
+
| **ICU support** | ⚠️ WIP | ⚠️ Via plugin (i18next-icu) | ✅ Yes | ✅ Yes | ✅ Yes | ⚠️ Via plugin (`i18next-icu`) | ⚠️ Via custom formatter/compiler |
|
|
257
|
+
| **SEO Helpers (hreflang, sitemap)** | ✅ Built-in tools: helpers for sitemap, robots.txt, metadata | ⚠️ Community plugins/manual | ❌ Not core | ❌ Not core | ✅ Good | ✅ Good | ❌ Not core (Nuxt i18n provides helpers) |
|
|
258
|
+
| **Ecosystem / Community** | ⚠️ Smaller but growing fast and reactive | ✅ Largest and mature | ✅ Large | ⚠️ Smaller | ✅ Mid-size, Next.js-focused | ✅ Mid-size, Next.js-focused | ✅ Large in Vue ecosystem |
|
|
259
|
+
| **Server-side Rendering & Server Components** | ✅ Yes, streamlined for SSR / React Server Components | ⚠️ Supported at page level but need to pass t-functions on component tree for children server components | ⚠️ Supported at page level with additional set up, but need to pass t-functions on component tree for children server components | ✅ Supported, set up needed | ⚠️ Supported at page level but need to pass t-functions on component tree for children server components | ⚠️ Supported at page level but need to pass t-functions on component tree for children server components | ✅ SSR via Nuxt/Vue SSR (no RSC) |
|
|
260
|
+
| **Tree-shaking (load only used content)** | ✅ Yes, per-component at build time via Babel/SWC plugins | ⚠️ Usually loads all (can be improved with namespaces/code-splitting) | ⚠️ Usually loads all | ❌ Not default | ⚠️ Partial | ⚠️ Partial | ⚠️ Partial (with code-splitting/manual setup) |
|
|
261
|
+
| **Lazy loading** | ✅ Yes, per-locale / per-dictionary | ✅ Yes (e.g., backends/namespaces on demand) | ✅ Yes (split locale bundles) | ✅ Yes (dynamic catalog imports) | ✅ Yes (per-route/per-locale), need mamespace management | ✅ Yes (per-route/per-locale), need mamespace management | ✅ Yes (async locale messages) |
|
|
262
|
+
| **Purge unused content** | ✅ Yes, per-dictionary at build time | ❌ No, only via manual namespace segmentation | ❌ No, all declared messages are bundled | ✅ Yes, unused keys detected & dropped at build | ❌ No, can be managed manually with namespace management | ❌ No, can be managed manually with namespace management | ❌ No, only possible via manual lazy-loading |
|
|
263
|
+
| **Management of Large Projects** | ✅ Encourages modular, suited for design-system | ⚠️ Needs good file discipline | ⚠️ Central catalogs can get large | ⚠️ May get complex | ✅ Modular with setup | ✅ Modular with setup | ✅ Modular with Vue Router/Nuxt i18n setup |
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Interoperability
|
|
268
|
+
|
|
269
|
+
`intlayer` can also help to manage your `react-intl`, `react-i18next`, `next-intl`, `next-i18next`, and `vue-i18n` namespaces.
|
|
270
|
+
|
|
271
|
+
Using `intlayer`, you can declare your content in the format of your favorite i18n library, and intlayer will generate your namespaces in the location of your choice (example: `/messages/{{locale}}/{{namespace}}.json`).
|
|
272
|
+
|
|
273
|
+
Refer to [`dictionaryOutput` and `i18nextResourcesDir` options](https://intlayer.org/doc/concept/configuration#content-configuration) for more details.
|
|
263
274
|
|
|
264
275
|
## Document History
|
|
265
276
|
|