nuxt-i18n-micro 1.3.1 → 1.5.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/README.md CHANGED
@@ -276,17 +276,31 @@ const i18n = useI18n()
276
276
  </script>
277
277
 
278
278
  ```
279
+ Вот обновленный раздел `README.md` с описанием работы параметра `routesLocaleLinks` и улучшенным оформлением параметров модуля.
279
280
 
280
281
  ## Module Options
281
282
 
282
283
  The module accepts the following options in the Nuxt configuration:
283
284
 
284
- **locales**: An array of locale objects. Each locale should have the following properties:
285
+ ### **locales**: `Locale[]`
285
286
 
286
- - **code**: *(string, required)* A unique identifier for the locale, such as `'en'` for English or `'fr'` for French.
287
- - **iso**: *(string, optional)* The ISO code for the locale, which is typically used for setting the `lang` attribute in HTML or for other internationalization purposes (e.g., `'en-US'`, `'fr-FR'`).
288
- - **dir**: *(string, optional)* The text direction for the locale. It can be either `'rtl'` for right-to-left languages (like Arabic or Hebrew) or `'ltr'` for left-to-right languages (like English or French). This is useful for ensuring that text is displayed correctly depending on the language's writing system.
289
- - **disabled**: *(boolean, optional)* A flag indicating whether this locale should be disabled or excluded from certain layers or operations. When `disabled` is set to `true`, this locale will be ignored in situations where only active or enabled locales are considered. This can be particularly useful when working with different layers of content or features in a multi-locale application, allowing developers to temporarily or permanently exclude specific locales from being processed, displayed, or made available to users without removing them entirely from the configuration.
287
+ ```typescript
288
+ interface Locale {
289
+ code: string
290
+ disabled?: boolean
291
+ iso?: string
292
+ dir?: 'rtl' | 'ltr'
293
+ }
294
+ ```
295
+
296
+ An array of locale objects. Each locale should have the following properties:
297
+
298
+ - **`code`**: *(string, required)* A unique identifier for the locale, such as `'en'` for English or `'fr'` for French.
299
+ - **`iso`**: *(string, optional)* The ISO code for the locale, which is typically used for setting the `lang` attribute in HTML or for other internationalization purposes (e.g., `'en-US'`, `'fr-FR'`).
300
+ - **`dir`**: *(string, optional)* The text direction for the locale. It can be either `'rtl'` for right-to-left languages (like Arabic or Hebrew) or `'ltr'` for left-to-right languages (like English or French).
301
+ - **`disabled`**: *(boolean, optional)* A flag indicating whether this locale should be disabled or excluded from certain layers or operations.
302
+
303
+ Example:
290
304
 
291
305
  ```typescript
292
306
  locales: [
@@ -296,19 +310,55 @@ locales: [
296
310
  ]
297
311
  ```
298
312
 
299
- **meta**: A boolean indicating whether to automatically generate SEO-related meta tags (like `alternate` links).
313
+ ### **meta**: `boolean`
314
+
315
+ Indicates whether to automatically generate SEO-related meta tags (like `alternate` links).
316
+
317
+ ### **defaultLocale**: `string`
318
+
319
+ The default locale code. For example, `'en'`.
320
+
321
+ ### **translationDir**: `string`
322
+
323
+ The directory where translation files are stored. Default value is `'locales'`.
324
+
325
+ ### **autoDetectLanguage**: `boolean`
326
+
327
+ If `true`, the module automatically detects the user's preferred language and redirects accordingly.
328
+
329
+ ### **plural**: `function`
300
330
 
301
- **defaultLocale**: The default locale code (e.g., `'en'`).
331
+ A custom function for handling pluralization logic.
302
332
 
303
- **translationDir**: The directory where translation files are stored (e.g., `'locales'`).
333
+ ### **includeDefaultLocaleRoute**: `boolean`
304
334
 
305
- **autoDetectLanguage**: If `true`, automatically detects the user's preferred language and redirects accordingly.
335
+ If `true`, all routes without a locale prefix will redirect to the default locale route.
336
+
337
+ ### **routesLocaleLinks**: `Record<string, string>`
338
+
339
+ This parameter allows you to create links between different pages' locale files. It is particularly useful in cases where you have similar pages (e.g., a main page and a page with a slug) and want them to share the same translation file.
340
+
341
+ For example, if you have a page with a slug (`dir1-slug`) and a main page (`index`), you can set up `routesLocaleLinks` so that `dir1-slug` will use the locale file of `index`, avoiding the need to maintain duplicate translation files.
342
+
343
+ **Note**: `dir1-slug` and `index` refer to the names of the routes, which you can inspect in the devtools.
344
+
345
+ Example:
346
+
347
+ ```typescript
348
+ export default defineNuxtConfig({
349
+ i18n: {
350
+ routesLocaleLinks: {
351
+ 'dir1-slug': 'index',
352
+ },
353
+ },
354
+ })
355
+ ```
306
356
 
307
- **plural**: A custom function for handling pluralization.
357
+ In this example, the page with the route name `dir1-slug` will load its translations from the locale file associated with the `index` route.
308
358
 
309
- **includeDefaultLocaleRoute**: A boolean. If enabled, all routes without a locale prefix will redirect to the default locale route.
359
+ ### **cache**: `boolean`
310
360
 
311
- **cache**: (In development) A boolean option designed to optimize performance when working with large JSON translation files. When enabled, it caches translations specific to the current page, reducing search times and minimizing client-side load. This cached data is then sent to the client, resulting in faster page loads and improved user experience.
361
+ (In development) This option is designed to optimize performance when working with large JSON translation files. When enabled, it caches translations specific to the current page, reducing search times and minimizing client-side load.
312
362
 
313
363
  ## Locale Loading in Nuxt I18n Micro
314
364
 
@@ -9,4 +9,4 @@
9
9
  <link rel="prefetch" as="style" href="/__nuxt-i18n-micro/_nuxt/error-500.B4KzowuE.css">
10
10
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DrEIrqkc.js">
11
11
  <script type="module" src="/__nuxt-i18n-micro/_nuxt/Cnou2wpD.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
12
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"24c3ebe6-b58c-4b9b-95e1-e8ef9ca69f47",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
12
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"d62c5b85-c72c-4371-bfa7-3402c13237f3",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
@@ -9,4 +9,4 @@
9
9
  <link rel="prefetch" as="style" href="/__nuxt-i18n-micro/_nuxt/error-500.B4KzowuE.css">
10
10
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DrEIrqkc.js">
11
11
  <script type="module" src="/__nuxt-i18n-micro/_nuxt/Cnou2wpD.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
12
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"24c3ebe6-b58c-4b9b-95e1-e8ef9ca69f47",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
12
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"d62c5b85-c72c-4371-bfa7-3402c13237f3",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
@@ -1 +1 @@
1
- {"id":"24c3ebe6-b58c-4b9b-95e1-e8ef9ca69f47","timestamp":1724148685666}
1
+ {"id":"d62c5b85-c72c-4371-bfa7-3402c13237f3","timestamp":1724181280320}
@@ -0,0 +1 @@
1
+ {"id":"d62c5b85-c72c-4371-bfa7-3402c13237f3","timestamp":1724181280320,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -9,4 +9,4 @@
9
9
  <link rel="prefetch" as="style" href="/__nuxt-i18n-micro/_nuxt/error-500.B4KzowuE.css">
10
10
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/DrEIrqkc.js">
11
11
  <script type="module" src="/__nuxt-i18n-micro/_nuxt/Cnou2wpD.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
12
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"24c3ebe6-b58c-4b9b-95e1-e8ef9ca69f47",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
12
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"d62c5b85-c72c-4371-bfa7-3402c13237f3",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
package/dist/module.d.mts CHANGED
@@ -14,6 +14,7 @@ interface ModuleOptions {
14
14
  translationDir?: string;
15
15
  autoDetectLanguage?: boolean;
16
16
  includeDefaultLocaleRoute?: boolean;
17
+ routesLocaleLinks?: Record<string, string>;
17
18
  cache?: boolean;
18
19
  plural?: string;
19
20
  }
@@ -21,6 +22,8 @@ interface ModuleOptionsExtend extends ModuleOptions {
21
22
  rootDir: string;
22
23
  pluralString: string;
23
24
  rootDirs: string[];
25
+ dateBuild: number;
26
+ baseURL: string;
24
27
  }
25
28
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
26
29
 
package/dist/module.d.ts CHANGED
@@ -14,6 +14,7 @@ interface ModuleOptions {
14
14
  translationDir?: string;
15
15
  autoDetectLanguage?: boolean;
16
16
  includeDefaultLocaleRoute?: boolean;
17
+ routesLocaleLinks?: Record<string, string>;
17
18
  cache?: boolean;
18
19
  plural?: string;
19
20
  }
@@ -21,6 +22,8 @@ interface ModuleOptionsExtend extends ModuleOptions {
21
22
  rootDir: string;
22
23
  pluralString: string;
23
24
  rootDirs: string[];
25
+ dateBuild: number;
26
+ baseURL: string;
24
27
  }
25
28
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
26
29
 
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-i18n-micro",
3
3
  "configKey": "i18n",
4
- "version": "1.3.1",
4
+ "version": "1.5.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.3",
7
7
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -101,6 +101,7 @@ const module = defineNuxtModule({
101
101
  translationDir: "locales",
102
102
  autoDetectLanguage: true,
103
103
  includeDefaultLocaleRoute: false,
104
+ routesLocaleLinks: {},
104
105
  cache: false,
105
106
  plural: `function (translation, count, _locale) {
106
107
  const forms = translation.toString().split('|')
@@ -135,7 +136,10 @@ const module = defineNuxtModule({
135
136
  translationDir: options.translationDir ?? "locales",
136
137
  autoDetectLanguage: options.autoDetectLanguage ?? true,
137
138
  includeDefaultLocaleRoute: options.includeDefaultLocaleRoute ?? false,
138
- cache: options.cache ?? false
139
+ routesLocaleLinks: options.routesLocaleLinks ?? {},
140
+ cache: options.cache ?? false,
141
+ dateBuild: Date.now(),
142
+ baseURL: nuxt.options.app.baseURL
139
143
  };
140
144
  addPlugin({
141
145
  src: resolver.resolve("./runtime/plugins/01.plugin"),
@@ -177,7 +181,7 @@ const module = defineNuxtModule({
177
181
  const localeRegex = locales.filter((locale) => locale.code !== options.defaultLocale || options.includeDefaultLocaleRoute).map((locale) => locale.code).join("|");
178
182
  const pagesDir = path.resolve(nuxt.options.rootDir, options.translationDir, "pages");
179
183
  extendPages((pages) => {
180
- const pagesNames = pages.map((page) => page.name);
184
+ const pagesNames = pages.map((page) => page.name).filter((name) => name && (!options.routesLocaleLinks || !options.routesLocaleLinks[name]));
181
185
  function ensureFileExists(filePath) {
182
186
  const fileDir = path.dirname(filePath);
183
187
  if (!existsSync(fileDir)) {
@@ -190,21 +194,19 @@ const module = defineNuxtModule({
190
194
  locales.forEach((locale) => {
191
195
  const globalFilePath = path.join(nuxt.options.rootDir, options.translationDir, `${locale.code}.json`);
192
196
  ensureFileExists(globalFilePath);
193
- pages.forEach((page) => {
194
- const pageFilePath = path.join(pagesDir, `${page.name}/${locale.code}.json`);
197
+ pagesNames.forEach((name) => {
198
+ const pageFilePath = path.join(pagesDir, `${name}/${locale.code}.json`);
195
199
  ensureFileExists(pageFilePath);
196
200
  });
197
201
  });
198
- const newRoutes = pages.map((page) => {
199
- return {
200
- ...page,
201
- path: `/:locale(${localeRegex})${page.path}`,
202
- name: `localized-${page.name}`,
203
- meta: {
204
- ...page.meta
205
- }
206
- };
207
- });
202
+ const newRoutes = pages.map((page) => ({
203
+ ...page,
204
+ path: `/:locale(${localeRegex})${page.path}`,
205
+ name: `localized-${page.name}`,
206
+ meta: {
207
+ ...page.meta
208
+ }
209
+ }));
208
210
  pages.push(...newRoutes);
209
211
  nuxt.options.generate.routes = Array.isArray(nuxt.options.generate.routes) ? nuxt.options.generate.routes : [];
210
212
  locales.forEach((locale) => {
@@ -54,3 +54,14 @@ declare module 'vue' {
54
54
  interface ComponentCustomProperties extends PluginsInjections {
55
55
  }
56
56
  }
57
+ declare global {
58
+ const $getLocale: () => string;
59
+ const $getLocales: () => Locale[];
60
+ const $t: <T extends Record<string, string | number | boolean>>(key: string, params?: T, defaultValue?: string) => string | number | boolean | Translations | PluralTranslations | unknown[] | unknown | null;
61
+ const $tc: (key: string, count: number, defaultValue?: string) => string;
62
+ const $has: (key: string) => boolean;
63
+ const $mergeTranslations: (newTranslations: Translations) => void;
64
+ const $switchLocale: (locale: string) => void;
65
+ const $localeRoute: (to: RouteLocationRaw, locale?: string) => RouteLocationRaw;
66
+ const $loadPageTranslations: (locale: string, routeName: string) => Promise<void>;
67
+ }
@@ -66,26 +66,33 @@ export default defineNuxtPlugin(async (nuxtApp) => {
66
66
  const route = useRoute();
67
67
  const config = useRuntimeConfig();
68
68
  const i18nConfig = config.public.i18nConfig;
69
- const initialLocale = (route.params?.locale ?? i18nConfig.defaultLocale).toString();
70
- const initialRouteName = route.name.replace(`localized-`, "");
71
69
  const plural = new Function("return " + i18nConfig.plural)();
72
70
  router.beforeEach(async (to, from, next) => {
73
71
  if (import.meta.client) {
74
72
  const locale = (to.params?.locale ?? i18nConfig.defaultLocale).toString();
75
- const routeName = to.name.replace(`localized-`, "");
76
- if (!i18nHelper.hasPageTranslation(locale, routeName)) {
77
- const data2 = await $fetch(`/_locales/${routeName}/${locale}/data.json`);
78
- await i18nHelper.loadPageTranslations(locale, routeName, data2 ?? {});
73
+ const initialRouteName2 = to.name.replace(`localized-`, "");
74
+ let routeName = initialRouteName2;
75
+ if (i18nConfig.routesLocaleLinks && i18nConfig.routesLocaleLinks[routeName]) {
76
+ routeName = i18nConfig.routesLocaleLinks[routeName];
77
+ }
78
+ if (!i18nHelper.hasPageTranslation(locale, initialRouteName2)) {
79
+ const data2 = await $fetch(`/_locales/${routeName}/${locale}/data.json?v=${i18nConfig.dateBuild}`, { baseURL: i18nConfig.baseURL });
80
+ await i18nHelper.loadPageTranslations(locale, initialRouteName2, data2 ?? {});
79
81
  }
80
82
  }
81
83
  next();
82
84
  });
83
- const data = await $fetch(`/_locales/general/${initialLocale}/data.json`);
85
+ const initialLocale = (route.params?.locale ?? i18nConfig.defaultLocale).toString();
86
+ const initialRouteName = route.name.replace(`localized-`, "");
87
+ const data = await $fetch(`/_locales/general/${initialLocale}/data.json?v=${i18nConfig.dateBuild}`, { baseURL: i18nConfig.baseURL });
84
88
  await i18nHelper.loadTranslations(initialLocale, initialRouteName, data ?? {});
85
89
  if (import.meta.server) {
86
90
  const locale = (route.params?.locale ?? i18nConfig.defaultLocale).toString();
87
- const routeName = route.name.replace(`localized-`, "");
88
- const data2 = await $fetch(`/_locales/${routeName}/${locale}/data.json`);
91
+ let routeName = initialRouteName;
92
+ if (i18nConfig.routesLocaleLinks && i18nConfig.routesLocaleLinks[routeName]) {
93
+ routeName = i18nConfig.routesLocaleLinks[routeName];
94
+ }
95
+ const data2 = await $fetch(`/_locales/${routeName}/${locale}/data.json?v=${i18nConfig.dateBuild}`, { baseURL: i18nConfig.baseURL });
89
96
  await i18nHelper.loadPageTranslations(initialLocale, initialRouteName, data2 ?? {});
90
97
  }
91
98
  return {
@@ -32,6 +32,7 @@ export default defineNuxtPlugin((_nuxtApp) => {
32
32
  if (i18nConfig.includeDefaultLocaleRoute) {
33
33
  defaultRouteName = `localized-${defaultRouteName}`;
34
34
  newParams.locale = i18nConfig.defaultLocale;
35
+ newParams.name = defaultRouteName;
35
36
  }
36
37
  return router.push(resolvedRoute);
37
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-i18n-micro",
3
- "version": "1.3.1",
3
+ "version": "1.5.0",
4
4
  "description": "Nuxt I18n Micro is a lightweight, high-performance internationalization module for Nuxt, designed to handle multi-language support with minimal overhead, fast build times, and efficient runtime performance.",
5
5
  "repository": "s00d/nuxt-i18n-micro",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"id":"24c3ebe6-b58c-4b9b-95e1-e8ef9ca69f47","timestamp":1724148685666,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}