nuxt-i18n-micro 3.17.5 → 3.18.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/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/bdfcba12-33f4-4120-bce9-f186efc3683a.json +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +8 -4
- package/dist/runtime/composables/useI18nLocale.js +6 -3
- package/dist/runtime/plugins/01.plugin.d.ts +2 -58
- package/dist/runtime/plugins/01.plugin.js +6 -2
- package/dist/runtime/plugins/02.meta.js +5 -1
- package/dist/runtime/plugins/05.hooks.js +5 -1
- package/dist/runtime/plugins/06.redirect.js +7 -2
- package/dist/runtime/server/middleware/i18n.global.js +8 -2
- package/dist/runtime/server/routes/i18n.js +8 -2
- package/dist/runtime/server/utils/locale-server-middleware.js +12 -4
- package/dist/runtime/server/utils/server-loader.js +5 -3
- package/dist/runtime/server/utils/translation-server-middleware.js +9 -2
- package/dist/runtime/utils/active-locales.d.ts +4 -0
- package/dist/runtime/utils/active-locales.js +9 -0
- package/dist/runtime/utils/runtime-i18n-config.d.ts +8 -0
- package/dist/runtime/utils/runtime-i18n-config.js +90 -0
- package/package.json +3 -3
- package/dist/client/_nuxt/builds/meta/27df88ba-c559-40f5-a972-a7bb2444b9fc.json +0 -1
package/dist/client/200.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Brscz0ku.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Dt5GiM1K.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CXlkzKTu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Brscz0ku.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Dt5GiM1K.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CXlkzKTu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"bdfcba12-33f4-4120-bce9-f186efc3683a",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1778844297940,false]</script></body></html>
|
package/dist/client/404.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Brscz0ku.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Dt5GiM1K.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CXlkzKTu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Brscz0ku.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Dt5GiM1K.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CXlkzKTu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"bdfcba12-33f4-4120-bce9-f186efc3683a",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1778844297940,false]</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"bdfcba12-33f4-4120-bce9-f186efc3683a","timestamp":1778844295058}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"bdfcba12-33f4-4120-bce9-f186efc3683a","timestamp":1778844295058,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
package/dist/client/index.html
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Brscz0ku.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Dt5GiM1K.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CXlkzKTu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Kj_DYE7z.css" crossorigin><link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js"><script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/D_aXYej0.js" crossorigin></script><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.CyBDSRXN.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Brscz0ku.js"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/Dt5GiM1K.js"><link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.DJtCwW7w.css"><link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CXlkzKTu.js"></head><body><div id="__nuxt"></div><div id="teleports"></div><script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"bdfcba12-33f4-4120-bce9-f186efc3683a",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1778844297940,false]</script></body></html>
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { createRequire } from 'node:module';
|
|
|
4
4
|
import path, { resolve, join, dirname } from 'node:path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
6
6
|
import { defaultPlural, isNoPrefixStrategy, withPrefixStrategy } from '@i18n-micro/core';
|
|
7
|
-
import { RouteGenerator, normalizePath, isInternalPath } from '@i18n-micro/route-strategy';
|
|
7
|
+
import { RouteGenerator, isLocaleAllowedForUnlocalizedRoute, normalizePath, isInternalPath } from '@i18n-micro/route-strategy';
|
|
8
8
|
import { useNuxt, defineNuxtModule, useLogger, createResolver, addTemplate, addImportsDir, addPlugin, addServerHandler, addComponentsDir, addTypeTemplate, addPrerenderRoutes } from '@nuxt/kit';
|
|
9
9
|
import { globby } from 'globby';
|
|
10
10
|
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
@@ -451,7 +451,7 @@ const module = defineNuxtModule({
|
|
|
451
451
|
await preMergeLocales(rootDirs, translationDirName, mergedLocalesDir, localeInfos, options.fallbackLocale, options.disablePageLocales);
|
|
452
452
|
logger.info(`Pre-merged translations from ${rootDirs.length} layer(s) into ${mergedLocalesDir}`);
|
|
453
453
|
});
|
|
454
|
-
const routeLocales = {};
|
|
454
|
+
const routeLocales = { ...options.routeLocales ?? {} };
|
|
455
455
|
const globalLocaleRoutes = {};
|
|
456
456
|
const routeDisableMeta = {};
|
|
457
457
|
const pageFiles = await globby(["pages/**/*.vue", "app/pages/**/*.vue"], { cwd: nuxt.options.rootDir });
|
|
@@ -562,8 +562,6 @@ const module = defineNuxtModule({
|
|
|
562
562
|
cacheMaxSize: options.cacheMaxSize ?? 0,
|
|
563
563
|
cacheTtl: options.cacheTtl ?? 0
|
|
564
564
|
};
|
|
565
|
-
nuxt.options.runtimeConfig.public = nuxt.options.runtimeConfig.public || {};
|
|
566
|
-
nuxt.options.runtimeConfig.public.i18nConfig = fullConfig;
|
|
567
565
|
const fullConfigJson = JSON.stringify(fullConfig);
|
|
568
566
|
const strategyTemplate = addTemplate({
|
|
569
567
|
filename: "i18n.strategy.mjs",
|
|
@@ -811,6 +809,9 @@ declare module '#i18n-internal/plural' {
|
|
|
811
809
|
if (originalPath.startsWith("/api")) continue;
|
|
812
810
|
routeGenerator.locales.forEach((localeObj) => {
|
|
813
811
|
const localeCode = localeObj.code;
|
|
812
|
+
if (!isLocaleAllowedForUnlocalizedRoute(routeGenerator.routeLocales, routeGenerator.locales, originalPath, localeCode)) {
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
814
815
|
const localizedPath = routeGenerator.resolveLocalizedPath(originalPath, localeCode);
|
|
815
816
|
if (localizedPath === originalPath || localizedPath === normalizePath(originalPath)) {
|
|
816
817
|
return;
|
|
@@ -878,6 +879,9 @@ declare module '#i18n-internal/plural' {
|
|
|
878
879
|
continue;
|
|
879
880
|
}
|
|
880
881
|
for (const locale of routeGenerator.locales) {
|
|
882
|
+
if (!isLocaleAllowedForUnlocalizedRoute(routeGenerator.routeLocales, routeGenerator.locales, route, locale.code)) {
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
881
885
|
const localizedRoute = routeGenerator.resolveLocalizedPath(route, locale.code);
|
|
882
886
|
if (localizedRoute === route) {
|
|
883
887
|
continue;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { useState } from "#app";
|
|
1
|
+
import { useNuxtApp, useState } from "#app";
|
|
2
2
|
import { getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
3
3
|
import { useCookie } from "#imports";
|
|
4
|
+
import { getEnabledLocaleCodes } from "../utils/active-locales.js";
|
|
4
5
|
import { getHashCookieName, getLocaleCookieName, getLocaleCookieOptions } from "../utils/cookie.js";
|
|
6
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
5
7
|
export function useI18nLocale() {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
+
const nuxtApp = useNuxtApp();
|
|
9
|
+
const i18nConfig = resolveI18nConfigWithRuntimeOverrides(nuxtApp.$getI18nConfig?.() ?? getI18nConfig());
|
|
10
|
+
const validLocales = getEnabledLocaleCodes(i18nConfig.locales);
|
|
8
11
|
const localeState = useState("i18n-locale", () => null);
|
|
9
12
|
const localeCookieName = getLocaleCookieName(i18nConfig);
|
|
10
13
|
const hashCookieName = getHashCookieName(i18nConfig);
|
|
@@ -2,35 +2,7 @@ import type { PathStrategy } from '@i18n-micro/path-strategy';
|
|
|
2
2
|
import type { CleanTranslation, I18nRouteParams, Locale, MissingHandler, ModuleOptionsExtend, Params, Translations } from '@i18n-micro/types';
|
|
3
3
|
import type { RouteLocationNamedRaw, RouteLocationNormalizedLoaded, RouteLocationRaw, RouteLocationResolved, RouteLocationResolvedGeneric } from 'vue-router';
|
|
4
4
|
declare const _default: import("nuxt/app").Plugin<{
|
|
5
|
-
getI18nConfig: () =>
|
|
6
|
-
locales: never[];
|
|
7
|
-
metaTrustForwardedHost: boolean;
|
|
8
|
-
metaTrustForwardedProto: boolean;
|
|
9
|
-
defaultLocale: string;
|
|
10
|
-
localeCookie: null;
|
|
11
|
-
autoDetectLanguage: boolean;
|
|
12
|
-
autoDetectPath: string;
|
|
13
|
-
strategy: string;
|
|
14
|
-
dateBuild: number;
|
|
15
|
-
hashMode: boolean;
|
|
16
|
-
apiBaseUrl: string;
|
|
17
|
-
isSSG: boolean;
|
|
18
|
-
disablePageLocales: boolean;
|
|
19
|
-
canonicalQueryWhitelist: string[];
|
|
20
|
-
excludePatterns: never[];
|
|
21
|
-
routeLocales: {};
|
|
22
|
-
routeDisableMeta: {};
|
|
23
|
-
globalLocaleRoutes: {};
|
|
24
|
-
missingWarn: boolean;
|
|
25
|
-
redirects: boolean;
|
|
26
|
-
hmr: boolean;
|
|
27
|
-
localizedRouteNamePrefix: string;
|
|
28
|
-
routesLocaleLinks: {};
|
|
29
|
-
noPrefixRedirect: boolean;
|
|
30
|
-
debug: boolean;
|
|
31
|
-
cacheMaxSize: number;
|
|
32
|
-
cacheTtl: number;
|
|
33
|
-
};
|
|
5
|
+
getI18nConfig: () => ModuleOptionsExtend;
|
|
34
6
|
i18n: undefined;
|
|
35
7
|
__micro: boolean;
|
|
36
8
|
helper: {
|
|
@@ -63,35 +35,7 @@ declare const _default: import("nuxt/app").Plugin<{
|
|
|
63
35
|
loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
64
36
|
setMissingHandler: (handler: MissingHandler | null) => void;
|
|
65
37
|
}> & import("nuxt/app").ObjectPlugin<{
|
|
66
|
-
getI18nConfig: () =>
|
|
67
|
-
locales: never[];
|
|
68
|
-
metaTrustForwardedHost: boolean;
|
|
69
|
-
metaTrustForwardedProto: boolean;
|
|
70
|
-
defaultLocale: string;
|
|
71
|
-
localeCookie: null;
|
|
72
|
-
autoDetectLanguage: boolean;
|
|
73
|
-
autoDetectPath: string;
|
|
74
|
-
strategy: string;
|
|
75
|
-
dateBuild: number;
|
|
76
|
-
hashMode: boolean;
|
|
77
|
-
apiBaseUrl: string;
|
|
78
|
-
isSSG: boolean;
|
|
79
|
-
disablePageLocales: boolean;
|
|
80
|
-
canonicalQueryWhitelist: string[];
|
|
81
|
-
excludePatterns: never[];
|
|
82
|
-
routeLocales: {};
|
|
83
|
-
routeDisableMeta: {};
|
|
84
|
-
globalLocaleRoutes: {};
|
|
85
|
-
missingWarn: boolean;
|
|
86
|
-
redirects: boolean;
|
|
87
|
-
hmr: boolean;
|
|
88
|
-
localizedRouteNamePrefix: string;
|
|
89
|
-
routesLocaleLinks: {};
|
|
90
|
-
noPrefixRedirect: boolean;
|
|
91
|
-
debug: boolean;
|
|
92
|
-
cacheMaxSize: number;
|
|
93
|
-
cacheTtl: number;
|
|
94
|
-
};
|
|
38
|
+
getI18nConfig: () => ModuleOptionsExtend;
|
|
95
39
|
i18n: undefined;
|
|
96
40
|
__micro: boolean;
|
|
97
41
|
helper: {
|
|
@@ -6,6 +6,7 @@ import { createI18nStrategy, getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
|
6
6
|
import { createError, defineNuxtPlugin, navigateTo, useHead, useRouter, useRuntimeConfig } from "#imports";
|
|
7
7
|
import { useI18nLocale } from "../composables/useI18nLocale.js";
|
|
8
8
|
import { deepMergeTranslations } from "../utils/deep-merge.js";
|
|
9
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
9
10
|
import { translationStorage } from "../utils/storage.js";
|
|
10
11
|
const isDev = process.env.NODE_ENV !== "production";
|
|
11
12
|
const RE_TOKEN = /\{(\w+)\}/g;
|
|
@@ -22,8 +23,11 @@ function getByPath(obj, path) {
|
|
|
22
23
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
23
24
|
const router = useRouter();
|
|
24
25
|
const i18nStrategy = createI18nStrategy(router);
|
|
25
|
-
const i18nConfig = getI18nConfig();
|
|
26
26
|
const runtimeConfig = useRuntimeConfig();
|
|
27
|
+
const i18nConfig = resolveI18nConfigWithRuntimeOverrides(
|
|
28
|
+
getI18nConfig(),
|
|
29
|
+
runtimeConfig.public
|
|
30
|
+
);
|
|
27
31
|
translationStorage.configure({
|
|
28
32
|
maxSize: i18nConfig.cacheMaxSize ?? 0,
|
|
29
33
|
ttl: i18nConfig.cacheTtl ?? 0
|
|
@@ -379,7 +383,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
379
383
|
return {
|
|
380
384
|
provide: {
|
|
381
385
|
...provideData,
|
|
382
|
-
getI18nConfig: () =>
|
|
386
|
+
getI18nConfig: () => i18nConfig
|
|
383
387
|
}
|
|
384
388
|
};
|
|
385
389
|
});
|
|
@@ -3,9 +3,13 @@ import { getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
|
3
3
|
import { defineNuxtPlugin, useHead, useRequestURL, useRoute } from "#imports";
|
|
4
4
|
import { useLocaleHead } from "../composables/useLocaleHead.js";
|
|
5
5
|
import { isMetaDisabledForRoute } from "../utils/route-utils.js";
|
|
6
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
6
7
|
export default defineNuxtPlugin((nuxtApp) => {
|
|
7
8
|
const route = useRoute();
|
|
8
|
-
const
|
|
9
|
+
const getRuntimeConfig = nuxtApp.$getI18nConfig;
|
|
10
|
+
const i18nConfig = resolveI18nConfigWithRuntimeOverrides(
|
|
11
|
+
typeof getRuntimeConfig === "function" ? getRuntimeConfig() : getI18nConfig()
|
|
12
|
+
);
|
|
9
13
|
const currentLocale = nuxtApp.$getLocale?.();
|
|
10
14
|
if (isMetaDisabledForRoute(route, i18nConfig.routeDisableMeta, currentLocale)) {
|
|
11
15
|
return;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { isNoPrefixStrategy } from "@i18n-micro/core";
|
|
2
2
|
import { getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
3
3
|
import { defineNuxtPlugin, useNuxtApp, useRouter } from "#imports";
|
|
4
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
4
5
|
const isDev = process.env.NODE_ENV !== "production";
|
|
5
6
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
6
|
-
const
|
|
7
|
+
const getRuntimeConfig = nuxtApp.$getI18nConfig;
|
|
8
|
+
const i18nConfig = resolveI18nConfigWithRuntimeOverrides(
|
|
9
|
+
typeof getRuntimeConfig === "function" ? getRuntimeConfig() : getI18nConfig()
|
|
10
|
+
);
|
|
7
11
|
const router = useRouter();
|
|
8
12
|
const { $getLocale, $getRouteName } = useNuxtApp();
|
|
9
13
|
const i18nHelper = nuxtApp.$i18n.helper;
|
|
@@ -2,7 +2,9 @@ import { getCookie, getHeader, getRequestURL, setCookie } from "h3";
|
|
|
2
2
|
import { createI18nStrategy, getI18nConfig } from "#build/i18n.strategy.mjs";
|
|
3
3
|
import { createError, defineNuxtPlugin, navigateTo, useRequestEvent, useRoute, useRouter, useState } from "#imports";
|
|
4
4
|
import { useI18nLocale } from "../composables/useI18nLocale.js";
|
|
5
|
+
import { getEnabledLocaleCodes } from "../utils/active-locales.js";
|
|
5
6
|
import { getLocaleCookieName, getLocaleCookieOptions } from "../utils/cookie.js";
|
|
7
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../utils/runtime-i18n-config.js";
|
|
6
8
|
const DEBUG = process.env.NUXT_I18N_DEBUG_REDIRECT === "1";
|
|
7
9
|
const DEFAULT_STATIC_PATTERNS = [
|
|
8
10
|
/^\/sitemap.*\.xml$/,
|
|
@@ -53,8 +55,11 @@ export default defineNuxtPlugin({
|
|
|
53
55
|
setup(nuxtApp) {
|
|
54
56
|
const router = useRouter();
|
|
55
57
|
const i18nStrategy = createI18nStrategy(router);
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
+
const getRuntimeConfig = nuxtApp.$getI18nConfig;
|
|
59
|
+
const i18nConfig = resolveI18nConfigWithRuntimeOverrides(
|
|
60
|
+
typeof getRuntimeConfig === "function" ? getRuntimeConfig() : getI18nConfig()
|
|
61
|
+
);
|
|
62
|
+
const validLocales = getEnabledLocaleCodes(i18nConfig.locales);
|
|
58
63
|
const defaultLocale = i18nConfig.defaultLocale || "en";
|
|
59
64
|
const autoDetectPath = i18nConfig.autoDetectPath || "/";
|
|
60
65
|
const cookieName = getLocaleCookieName(i18nConfig);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { defineEventHandler, getCookie, getHeader, getQuery, getRequestURL } from "h3";
|
|
2
2
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
3
|
+
import { useRuntimeConfig } from "#imports";
|
|
4
|
+
import { getEnabledLocaleCodes } from "../../utils/active-locales.js";
|
|
3
5
|
import { getLocaleCookieName } from "../../utils/cookie.js";
|
|
6
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
4
7
|
function parseAcceptLanguage(header) {
|
|
5
8
|
if (!header) return [];
|
|
6
9
|
return header.split(",").map((entry) => {
|
|
@@ -12,8 +15,11 @@ export default defineEventHandler(async (event) => {
|
|
|
12
15
|
const path = event.path || getRequestURL(event).pathname;
|
|
13
16
|
if (path.startsWith("/api") || path.startsWith("/_nuxt") || path.startsWith("/_locales") || path.startsWith("/__")) return;
|
|
14
17
|
if (path.includes(".") && !path.endsWith(".html")) return;
|
|
15
|
-
const config =
|
|
16
|
-
|
|
18
|
+
const config = resolveI18nConfigWithRuntimeOverrides(
|
|
19
|
+
getI18nConfig(),
|
|
20
|
+
useRuntimeConfig(event).public
|
|
21
|
+
);
|
|
22
|
+
const validLocales = getEnabledLocaleCodes(config.locales);
|
|
17
23
|
const defaultLocale = config.defaultLocale || "en";
|
|
18
24
|
const pathSegments = path.split("/").filter(Boolean);
|
|
19
25
|
const firstSegment = pathSegments[0];
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { createError, defineEventHandler, getRouterParam, send, setResponseHeader } from "h3";
|
|
2
2
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
3
|
+
import { useRuntimeConfig } from "#imports";
|
|
4
|
+
import { isEnabledLocale } from "../../utils/active-locales.js";
|
|
5
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
3
6
|
import { loadTranslationsFromServer } from "../utils/server-loader.js";
|
|
4
7
|
export default defineEventHandler(async (event) => {
|
|
5
8
|
const page = getRouterParam(event, "page");
|
|
@@ -7,8 +10,11 @@ export default defineEventHandler(async (event) => {
|
|
|
7
10
|
if (!locale || !page) {
|
|
8
11
|
throw createError({ statusCode: 400, statusMessage: "Missing locale or page" });
|
|
9
12
|
}
|
|
10
|
-
const config =
|
|
11
|
-
|
|
13
|
+
const config = resolveI18nConfigWithRuntimeOverrides(
|
|
14
|
+
getI18nConfig(),
|
|
15
|
+
useRuntimeConfig(event).public
|
|
16
|
+
);
|
|
17
|
+
if (!isEnabledLocale(config.locales, locale)) {
|
|
12
18
|
throw createError({ statusCode: 404, statusMessage: "Locale not found" });
|
|
13
19
|
}
|
|
14
20
|
const { json } = await loadTranslationsFromServer(locale, page);
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
2
|
+
import { useRuntimeConfig } from "#imports";
|
|
3
|
+
import { getEnabledLocaleCodes, getEnabledLocales } from "../../utils/active-locales.js";
|
|
4
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
2
5
|
import { detectCurrentLocale } from "./locale-detector.js";
|
|
3
6
|
export const useLocaleServerMiddleware = (event, defaultLocale, currentLocale) => {
|
|
4
|
-
const {
|
|
7
|
+
const {
|
|
8
|
+
locales,
|
|
9
|
+
defaultLocale: configDefaultLocale,
|
|
10
|
+
fallbackLocale
|
|
11
|
+
} = resolveI18nConfigWithRuntimeOverrides(getI18nConfig(), useRuntimeConfig(event).public);
|
|
12
|
+
const enabledLocales = getEnabledLocales(locales);
|
|
5
13
|
const detectedLocale = currentLocale || detectCurrentLocale(
|
|
6
14
|
event,
|
|
7
15
|
{
|
|
8
16
|
fallbackLocale,
|
|
9
17
|
defaultLocale: defaultLocale || configDefaultLocale,
|
|
10
|
-
locales
|
|
18
|
+
locales: enabledLocales
|
|
11
19
|
},
|
|
12
20
|
defaultLocale
|
|
13
21
|
);
|
|
14
|
-
const localeConfig =
|
|
15
|
-
const availableLocales = locales
|
|
22
|
+
const localeConfig = enabledLocales.find((l) => l.code === detectedLocale) ?? null;
|
|
23
|
+
const availableLocales = getEnabledLocaleCodes(locales);
|
|
16
24
|
const isDefault = detectedLocale === (defaultLocale || configDefaultLocale || "en");
|
|
17
25
|
const isFallback = detectedLocale === (fallbackLocale || defaultLocale || configDefaultLocale || "en");
|
|
18
26
|
return {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { useStorage } from "nitropack/runtime";
|
|
2
2
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
3
|
+
import { isEnabledLocale } from "../../utils/active-locales.js";
|
|
3
4
|
import { CacheControl } from "../../utils/cache-control.js";
|
|
5
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
4
6
|
const CC_KEY = Symbol.for("__NUXT_I18N_SERVER_CACHE_CC__");
|
|
5
7
|
function getServerCacheControl() {
|
|
6
8
|
const g = globalThis;
|
|
7
9
|
if (!g[CC_KEY]) {
|
|
8
|
-
const cfg = getI18nConfig();
|
|
10
|
+
const cfg = resolveI18nConfigWithRuntimeOverrides(getI18nConfig());
|
|
9
11
|
g[CC_KEY] = new CacheControl({ maxSize: cfg.cacheMaxSize ?? 0, ttl: cfg.cacheTtl ?? 0 });
|
|
10
12
|
}
|
|
11
13
|
return g[CC_KEY];
|
|
@@ -25,8 +27,8 @@ export async function loadTranslationsFromServer(locale, routeName) {
|
|
|
25
27
|
if (cached) {
|
|
26
28
|
return cached;
|
|
27
29
|
}
|
|
28
|
-
const config = getI18nConfig();
|
|
29
|
-
if (!config.locales
|
|
30
|
+
const config = resolveI18nConfigWithRuntimeOverrides(getI18nConfig());
|
|
31
|
+
if (!isEnabledLocale(config.locales, locale)) {
|
|
30
32
|
const empty = { data: {}, json: "{}" };
|
|
31
33
|
cc.set(cacheKey, empty);
|
|
32
34
|
return empty;
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
import { interpolate } from "@i18n-micro/core";
|
|
2
2
|
import { getI18nConfig } from "#i18n-internal/strategy";
|
|
3
|
+
import { useRuntimeConfig } from "#imports";
|
|
4
|
+
import { getEnabledLocales } from "../../utils/active-locales.js";
|
|
5
|
+
import { resolveI18nConfigWithRuntimeOverrides } from "../../utils/runtime-i18n-config.js";
|
|
3
6
|
import { detectCurrentLocale } from "./locale-detector.js";
|
|
4
7
|
import { loadTranslationsFromServer } from "./server-loader.js";
|
|
5
8
|
const I18N_CONTEXT_KEY = "__i18n_translations__";
|
|
6
9
|
export const useTranslationServerMiddleware = async (event, defaultLocale, currentLocale) => {
|
|
7
|
-
const {
|
|
10
|
+
const {
|
|
11
|
+
locales,
|
|
12
|
+
fallbackLocale,
|
|
13
|
+
defaultLocale: configDefaultLocale
|
|
14
|
+
} = resolveI18nConfigWithRuntimeOverrides(getI18nConfig(), useRuntimeConfig(event).public);
|
|
8
15
|
const locale = currentLocale || event.context.i18n?.locale || detectCurrentLocale(
|
|
9
16
|
event,
|
|
10
17
|
{
|
|
11
18
|
fallbackLocale,
|
|
12
19
|
defaultLocale: defaultLocale || configDefaultLocale,
|
|
13
|
-
locales
|
|
20
|
+
locales: getEnabledLocales(locales)
|
|
14
21
|
},
|
|
15
22
|
defaultLocale
|
|
16
23
|
);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Locale } from '@i18n-micro/types';
|
|
2
|
+
export declare function getEnabledLocales(locales?: Locale[] | null): Locale[];
|
|
3
|
+
export declare function getEnabledLocaleCodes(locales?: Locale[] | null): string[];
|
|
4
|
+
export declare function isEnabledLocale(locales: Locale[] | null | undefined, code: string): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function getEnabledLocales(locales) {
|
|
2
|
+
return (locales ?? []).filter((locale) => !locale.disabled);
|
|
3
|
+
}
|
|
4
|
+
export function getEnabledLocaleCodes(locales) {
|
|
5
|
+
return getEnabledLocales(locales).map((locale) => locale.code);
|
|
6
|
+
}
|
|
7
|
+
export function isEnabledLocale(locales, code) {
|
|
8
|
+
return getEnabledLocales(locales).some((locale) => locale.code === code);
|
|
9
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ModuleOptionsExtend } from '@i18n-micro/types';
|
|
2
|
+
export interface RuntimeI18nOverrides {
|
|
3
|
+
defaultLocale?: string;
|
|
4
|
+
fallbackLocale?: string;
|
|
5
|
+
disabledLocales?: string[];
|
|
6
|
+
strategy?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function resolveI18nConfigWithRuntimeOverrides(baseConfig: ModuleOptionsExtend, runtimePublic?: Record<string, unknown>, warn?: (message: string) => void): ModuleOptionsExtend;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
function toNonEmptyString(value) {
|
|
2
|
+
if (typeof value !== "string") return void 0;
|
|
3
|
+
const normalized = value.trim();
|
|
4
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
5
|
+
}
|
|
6
|
+
function parseLocalesList(value) {
|
|
7
|
+
if (Array.isArray(value)) {
|
|
8
|
+
const items = value.map((entry) => toNonEmptyString(entry)).filter((entry) => Boolean(entry));
|
|
9
|
+
return items.length > 0 ? items : void 0;
|
|
10
|
+
}
|
|
11
|
+
if (typeof value === "string") {
|
|
12
|
+
const items = value.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
|
|
13
|
+
return items.length > 0 ? items : void 0;
|
|
14
|
+
}
|
|
15
|
+
return void 0;
|
|
16
|
+
}
|
|
17
|
+
function readEnvOverrides() {
|
|
18
|
+
return {
|
|
19
|
+
defaultLocale: toNonEmptyString(process.env.NUXT_I18N_DEFAULT_LOCALE) ?? toNonEmptyString(process.env.NUXT_PUBLIC_I18N_RUNTIME_DEFAULT_LOCALE),
|
|
20
|
+
fallbackLocale: toNonEmptyString(process.env.NUXT_I18N_FALLBACK_LOCALE) ?? toNonEmptyString(process.env.NUXT_PUBLIC_I18N_RUNTIME_FALLBACK_LOCALE),
|
|
21
|
+
disabledLocales: parseLocalesList(process.env.NUXT_I18N_DISABLED_LOCALES) ?? parseLocalesList(process.env.NUXT_PUBLIC_I18N_RUNTIME_DISABLED_LOCALES),
|
|
22
|
+
strategy: toNonEmptyString(process.env.NUXT_I18N_STRATEGY) ?? toNonEmptyString(process.env.NUXT_PUBLIC_I18N_RUNTIME_STRATEGY)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function readRuntimeOverrides(runtimePublic) {
|
|
26
|
+
const raw = runtimePublic?.i18nRuntime;
|
|
27
|
+
if (!raw || typeof raw !== "object") return {};
|
|
28
|
+
const runtime = raw;
|
|
29
|
+
return {
|
|
30
|
+
defaultLocale: toNonEmptyString(runtime.defaultLocale),
|
|
31
|
+
fallbackLocale: toNonEmptyString(runtime.fallbackLocale),
|
|
32
|
+
disabledLocales: parseLocalesList(runtime.disabledLocales),
|
|
33
|
+
strategy: toNonEmptyString(runtime.strategy)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function mergeOverrides(runtimePublic) {
|
|
37
|
+
const env = readEnvOverrides();
|
|
38
|
+
const runtime = readRuntimeOverrides(runtimePublic);
|
|
39
|
+
return {
|
|
40
|
+
defaultLocale: runtime.defaultLocale ?? env.defaultLocale,
|
|
41
|
+
fallbackLocale: runtime.fallbackLocale ?? env.fallbackLocale,
|
|
42
|
+
disabledLocales: runtime.disabledLocales ?? env.disabledLocales,
|
|
43
|
+
strategy: runtime.strategy ?? env.strategy
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function resolveI18nConfigWithRuntimeOverrides(baseConfig, runtimePublic, warn = (message) => console.warn(message)) {
|
|
47
|
+
const overrides = mergeOverrides(runtimePublic);
|
|
48
|
+
const locales = (baseConfig.locales ?? []).map((locale) => ({ ...locale }));
|
|
49
|
+
if (overrides.strategy && overrides.strategy !== baseConfig.strategy) {
|
|
50
|
+
warn(
|
|
51
|
+
`[nuxt-i18n-micro] runtime i18n strategy override is ignored: "${overrides.strategy}" (build strategy: "${baseConfig.strategy}"). Build a separate artifact for each strategy.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
if (overrides.disabledLocales && overrides.disabledLocales.length > 0) {
|
|
55
|
+
const disabledSet = new Set(overrides.disabledLocales);
|
|
56
|
+
for (const locale of locales) {
|
|
57
|
+
locale.disabled = disabledSet.has(locale.code);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const enabledLocales = locales.filter((locale) => !locale.disabled);
|
|
61
|
+
if (enabledLocales.length === 0) {
|
|
62
|
+
if (overrides.disabledLocales && overrides.disabledLocales.length > 0) {
|
|
63
|
+
warn("[nuxt-i18n-micro] runtime disabledLocales override would disable all locales; override ignored.");
|
|
64
|
+
}
|
|
65
|
+
return { ...baseConfig, locales: (baseConfig.locales ?? []).map((locale) => ({ ...locale })) };
|
|
66
|
+
}
|
|
67
|
+
const allLocaleCodes = new Set(locales.map((locale) => locale.code));
|
|
68
|
+
let defaultLocale = overrides.defaultLocale ?? baseConfig.defaultLocale;
|
|
69
|
+
let fallbackLocale = overrides.fallbackLocale ?? baseConfig.fallbackLocale;
|
|
70
|
+
if (fallbackLocale && !allLocaleCodes.has(fallbackLocale)) {
|
|
71
|
+
warn(`[nuxt-i18n-micro] runtime fallbackLocale "${fallbackLocale}" is not defined in locales; override ignored.`);
|
|
72
|
+
fallbackLocale = baseConfig.fallbackLocale;
|
|
73
|
+
}
|
|
74
|
+
const enabledLocaleCodes = new Set(enabledLocales.map((locale) => locale.code));
|
|
75
|
+
const firstEnabledLocale = enabledLocales[0]?.code ?? baseConfig.defaultLocale ?? "en";
|
|
76
|
+
if (!defaultLocale || !enabledLocaleCodes.has(defaultLocale)) {
|
|
77
|
+
if (overrides.defaultLocale) {
|
|
78
|
+
warn(`[nuxt-i18n-micro] runtime defaultLocale "${overrides.defaultLocale}" is not enabled; falling back to "${firstEnabledLocale}".`);
|
|
79
|
+
} else if (defaultLocale && !enabledLocaleCodes.has(defaultLocale)) {
|
|
80
|
+
warn(`[nuxt-i18n-micro] defaultLocale "${defaultLocale}" is disabled by runtime overrides; falling back to "${firstEnabledLocale}".`);
|
|
81
|
+
}
|
|
82
|
+
defaultLocale = firstEnabledLocale;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
...baseConfig,
|
|
86
|
+
locales,
|
|
87
|
+
defaultLocale,
|
|
88
|
+
fallbackLocale
|
|
89
|
+
};
|
|
90
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-i18n-micro",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.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",
|
|
@@ -76,9 +76,9 @@
|
|
|
76
76
|
"ufo": "^1.5.4",
|
|
77
77
|
"@i18n-micro/core": "1.3.0",
|
|
78
78
|
"@i18n-micro/path-strategy": "1.3.0",
|
|
79
|
-
"@i18n-micro/
|
|
79
|
+
"@i18n-micro/route-strategy": "1.1.6",
|
|
80
80
|
"@i18n-micro/types": "1.2.1",
|
|
81
|
-
"@i18n-micro/
|
|
81
|
+
"@i18n-micro/test-utils": "1.2.0"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@biomejs/biome": "^2.3.14",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"27df88ba-c559-40f5-a972-a7bb2444b9fc","timestamp":1777382527247,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|