nuxt-i18n-micro 3.30.2 → 4.0.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/LICENSE +1 -1
- package/README.md +2 -2
- package/dist/client/200.html +1 -1
- package/dist/client/404.html +1 -1
- package/dist/client/_nuxt/BVna_KKx.js +3 -0
- package/dist/client/_nuxt/Bw81RhAv.js +1 -0
- package/dist/client/_nuxt/CPz_jhsD.js +1 -0
- package/dist/client/_nuxt/CmvObVGq.js +1 -0
- package/dist/client/_nuxt/DKUOBR6F.js +5 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/f0c8d4bf-40d2-4915-8b4a-ebe46bde61c8.json +1 -0
- package/dist/client/_nuxt/{entry.BM-mexAv.css → entry.PSWtHhay.css} +1 -1
- package/dist/client/_nuxt/error-404.xs3fxhVJ.css +1 -0
- package/dist/client/_nuxt/error-500.C2S-4iLg.css +1 -0
- package/dist/client/index.html +1 -1
- package/dist/module.d.mts +14 -5
- package/dist/module.json +4 -1
- package/dist/module.mjs +850 -475
- package/dist/runtime/components/i18n-group.d.vue.ts +17 -9
- package/dist/runtime/components/i18n-group.vue +2 -4
- package/dist/runtime/components/i18n-group.vue.d.ts +17 -9
- package/dist/runtime/components/i18n-link.d.vue.ts +9 -6
- package/dist/runtime/components/i18n-link.vue +7 -28
- package/dist/runtime/components/i18n-link.vue.d.ts +9 -6
- package/dist/runtime/components/i18n-switcher.d.vue.ts +128 -54
- package/dist/runtime/components/i18n-switcher.vue +56 -156
- package/dist/runtime/components/i18n-switcher.vue.d.ts +128 -54
- package/dist/runtime/components/i18n-t.d.vue.ts +59 -116
- package/dist/runtime/components/i18n-t.vue +24 -71
- package/dist/runtime/components/i18n-t.vue.d.ts +59 -116
- package/dist/runtime/composables/useI18n.js +2 -38
- package/dist/runtime/composables/useI18nHead.js +21 -6
- package/dist/runtime/composables/useI18nLocale.d.ts +4 -1
- package/dist/runtime/composables/useI18nLocale.js +20 -22
- package/dist/runtime/composables/useLocaleHead.d.ts +26 -31
- package/dist/runtime/composables/useLocaleHead.js +47 -167
- package/dist/runtime/devtools/bridge.d.ts +2 -2
- package/dist/runtime/devtools/vue-devtools.d.ts +2 -2
- package/dist/runtime/devtools/vue-devtools.js +5 -5
- package/dist/runtime/middleware/i18n-redirect.global.d.ts +3 -2
- package/dist/runtime/middleware/i18n-redirect.global.js +30 -41
- package/dist/runtime/plugins/01.plugin.d.ts +156 -34
- package/dist/runtime/plugins/01.plugin.js +184 -138
- package/dist/runtime/plugins/02.meta.js +36 -43
- package/dist/runtime/plugins/04.vue-devtools.js +1 -1
- package/dist/runtime/plugins/06.redirect.d.ts +3 -3
- package/dist/runtime/plugins/06.redirect.js +65 -91
- package/dist/runtime/server/{utils → internal}/dev-live-translations.js +4 -3
- package/dist/runtime/server/internal/server-translation-cache.d.ts +9 -0
- package/dist/runtime/server/internal/server-translation-cache.js +10 -0
- package/dist/runtime/server/internal/shared-cache.d.ts +24 -0
- package/dist/runtime/server/internal/shared-cache.js +71 -0
- package/dist/runtime/server/internal/translation-watcher.d.ts +79 -0
- package/dist/runtime/server/internal/translation-watcher.js +105 -0
- package/dist/runtime/server/middleware/i18n.global.js +24 -37
- package/dist/runtime/server/payload-source.assets.d.ts +1 -0
- package/dist/runtime/server/payload-source.assets.js +3 -8
- package/dist/runtime/server/payload-source.fs.d.ts +1 -0
- package/dist/runtime/server/payload-source.fs.js +18 -7
- package/dist/runtime/server/plugins/failed-read.d.ts +7 -0
- package/dist/runtime/server/plugins/failed-read.js +23 -0
- package/dist/runtime/server/plugins/payload-cache.d.ts +6 -0
- package/dist/runtime/server/plugins/payload-cache.js +16 -0
- package/dist/runtime/server/plugins/watcher.dev.js +15 -79
- package/dist/runtime/server/routes/i18n.js +13 -14
- package/dist/runtime/server/utils/locale-detector.d.ts +32 -2
- package/dist/runtime/server/utils/locale-detector.js +48 -27
- package/dist/runtime/server/utils/locale-server-middleware.js +14 -33
- package/dist/runtime/server/utils/payload-cache.d.ts +4 -0
- package/dist/runtime/server/utils/payload-cache.js +13 -0
- package/dist/runtime/server/utils/server-loader.d.ts +17 -6
- package/dist/runtime/server/utils/server-loader.js +105 -51
- package/dist/runtime/server/utils/translation-server-middleware.js +18 -35
- package/dist/runtime/utils/cache-keys.d.ts +6 -0
- package/dist/runtime/utils/cache-keys.js +2 -0
- package/dist/runtime/utils/i18n-api.d.ts +185 -0
- package/dist/runtime/utils/i18n-api.js +196 -0
- package/dist/runtime/utils/i18n-config.d.ts +18 -0
- package/dist/runtime/utils/i18n-config.js +47 -0
- package/dist/runtime/utils/i18n-navigation.d.ts +26 -0
- package/dist/runtime/utils/i18n-navigation.js +96 -0
- package/dist/runtime/utils/nuxt-i18n-server.d.ts +26 -0
- package/dist/runtime/utils/nuxt-i18n-server.js +83 -0
- package/dist/runtime/utils/nuxt-i18n.d.ts +81 -96
- package/dist/runtime/utils/nuxt-i18n.js +180 -252
- package/dist/runtime/utils/page-head.d.ts +12 -0
- package/dist/runtime/utils/page-head.js +6 -0
- package/dist/runtime/utils/request-url.d.ts +6 -0
- package/dist/runtime/utils/request-url.js +11 -0
- package/dist/runtime/utils/storage.d.ts +31 -19
- package/dist/runtime/utils/storage.js +100 -49
- package/dist/runtime/utils/translation-entry.d.ts +6 -0
- package/dist/runtime/utils/translation-entry.js +16 -0
- package/dist/types.d.mts +4 -6
- package/internals.d.mts +9 -2
- package/package.json +78 -79
- package/dist/client/_nuxt/BOxWElQP.js +0 -21
- package/dist/client/_nuxt/CUWB4CwN.js +0 -3
- package/dist/client/_nuxt/CmUbe-uv.js +0 -1
- package/dist/client/_nuxt/DAzShkZF.js +0 -1
- package/dist/client/_nuxt/MokPP5zi.js +0 -1
- package/dist/client/_nuxt/builds/meta/f020fec8-462b-480b-82d8-6b0cb65617e8.json +0 -1
- package/dist/client/_nuxt/error-404.D9Svp6Hk.css +0 -1
- package/dist/client/_nuxt/error-500.B-mjI9_9.css +0 -1
- package/dist/runtime/plugins/03.define.d.ts +0 -7
- package/dist/runtime/plugins/03.define.js +0 -42
- package/dist/runtime/plugins/05.hooks.d.ts +0 -2
- package/dist/runtime/plugins/05.hooks.js +0 -47
- package/dist/runtime/server/utils/server-translation-cache.d.ts +0 -11
- package/dist/runtime/server/utils/server-translation-cache.js +0 -20
- /package/dist/runtime/server/{utils → internal}/dev-live-translations.d.ts +0 -0
|
@@ -1,26 +1,73 @@
|
|
|
1
1
|
import type { PathStrategy } from '@i18n-micro/path-strategy';
|
|
2
|
-
import type { CleanTranslation, DefineI18nRouteConfig, I18nRouteParams, Locale, MissingHandler,
|
|
2
|
+
import type { CleanTranslation, DefineI18nRouteConfig, I18nRouteParams, Locale, MissingHandler, ResolvedI18nConfig, Params, PluralFunc, Translations, TranslationKey } from '@i18n-micro/types';
|
|
3
3
|
import type { RouteLocationNamedRaw, RouteLocationNormalizedLoaded, RouteLocationRaw, RouteLocationResolved, RouteLocationResolvedGeneric } from 'vue-router';
|
|
4
|
+
import { type NuxtI18nPluginProvide } from '../utils/i18n-api.js';
|
|
4
5
|
import { type TranslationFn } from '../utils/nuxt-i18n.js';
|
|
5
6
|
export type { TranslationFn };
|
|
6
7
|
declare const _default: import("nuxt/app").Plugin<{
|
|
7
|
-
|
|
8
|
+
i18n: {
|
|
9
|
+
helper: {
|
|
10
|
+
mergeTranslation(locale: string, routeName: string, newTranslations: Translations): Promise<void>;
|
|
11
|
+
};
|
|
12
|
+
getI18nConfig: () => ResolvedI18nConfig;
|
|
13
|
+
__micro: boolean;
|
|
14
|
+
i18nStrategy: PathStrategy;
|
|
15
|
+
getLocale: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric) => string;
|
|
16
|
+
getLocaleName: () => string | null;
|
|
17
|
+
defaultLocale: () => string;
|
|
18
|
+
getLocales: () => Locale[];
|
|
19
|
+
getRouteName: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric, _locale?: string) => string;
|
|
20
|
+
t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeContext?: unknown) => CleanTranslation;
|
|
21
|
+
ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeContext?: unknown) => string;
|
|
22
|
+
_t: (route: RouteLocationNormalizedLoaded) => TranslationFn<CleanTranslation>;
|
|
23
|
+
_ts: (route: RouteLocationNormalizedLoaded) => TranslationFn<string>;
|
|
24
|
+
tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string;
|
|
25
|
+
pluralFunc: PluralFunc;
|
|
26
|
+
pluralLocale: () => string;
|
|
27
|
+
tn: {
|
|
28
|
+
(value: number, options?: Intl.NumberFormatOptions): string;
|
|
29
|
+
(value: number, key: string, overrides?: Intl.NumberFormatOptions): string;
|
|
30
|
+
(value: number, key: string, locale: string, overrides?: Intl.NumberFormatOptions): string;
|
|
31
|
+
};
|
|
32
|
+
td: {
|
|
33
|
+
(value: Date | number | string, options?: Intl.DateTimeFormatOptions): string;
|
|
34
|
+
(value: Date | number | string, key: string, overrides?: Intl.DateTimeFormatOptions): string;
|
|
35
|
+
(value: Date | number | string, key: string, locale: string, overrides?: Intl.DateTimeFormatOptions): string;
|
|
36
|
+
};
|
|
37
|
+
tdr: (value: Date | number | string, options?: Intl.RelativeTimeFormatOptions) => string;
|
|
38
|
+
has: (key: TranslationKey, routeContext?: unknown) => boolean;
|
|
39
|
+
resolveTranslations: (routeContext?: unknown) => Translations;
|
|
40
|
+
setTranslation: (key: TranslationKey, value: unknown) => void;
|
|
41
|
+
mergeTranslations: (newTranslations: Translations) => void;
|
|
42
|
+
switchLocaleRoute: (toLocale: string) => string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric;
|
|
43
|
+
clearCache: () => void;
|
|
44
|
+
switchLocalePath: (toLocale: string) => string;
|
|
45
|
+
switchLocale: (toLocale: string) => Promise<boolean>;
|
|
46
|
+
switchRoute: (route: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, toLocale?: string) => Promise<unknown>;
|
|
47
|
+
localeRoute(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): RouteLocationResolved;
|
|
48
|
+
localePath(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): string;
|
|
49
|
+
loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
50
|
+
setMissingHandler: (handler: MissingHandler | null) => void;
|
|
51
|
+
};
|
|
52
|
+
defineI18nRoute: ReturnType<({ getLocale, mergeTranslations }: Pick<NuxtI18nPluginProvide, "getLocale" | "mergeTranslations">) => ({ locales }: DefineI18nRouteConfig) => Promise<void>>;
|
|
8
53
|
helper: {
|
|
9
|
-
mergeTranslation(locale: string, routeName: string, newTranslations: Translations
|
|
54
|
+
mergeTranslation(locale: string, routeName: string, newTranslations: Translations): Promise<void>;
|
|
10
55
|
};
|
|
11
|
-
|
|
56
|
+
getI18nConfig: () => ResolvedI18nConfig;
|
|
12
57
|
__micro: boolean;
|
|
13
58
|
i18nStrategy: PathStrategy;
|
|
14
59
|
getLocale: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric) => string;
|
|
15
60
|
getLocaleName: () => string | null;
|
|
16
|
-
defaultLocale: () => string
|
|
61
|
+
defaultLocale: () => string;
|
|
17
62
|
getLocales: () => Locale[];
|
|
18
|
-
getRouteName: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric,
|
|
63
|
+
getRouteName: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric, _locale?: string) => string;
|
|
19
64
|
t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeContext?: unknown) => CleanTranslation;
|
|
20
|
-
ts: (key: TranslationKey, params?: Params, defaultValue?: string,
|
|
65
|
+
ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeContext?: unknown) => string;
|
|
21
66
|
_t: (route: RouteLocationNormalizedLoaded) => TranslationFn<CleanTranslation>;
|
|
22
67
|
_ts: (route: RouteLocationNormalizedLoaded) => TranslationFn<string>;
|
|
23
68
|
tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string;
|
|
69
|
+
pluralFunc: PluralFunc;
|
|
70
|
+
pluralLocale: () => string;
|
|
24
71
|
tn: {
|
|
25
72
|
(value: number, options?: Intl.NumberFormatOptions): string;
|
|
26
73
|
(value: number, key: string, overrides?: Intl.NumberFormatOptions): string;
|
|
@@ -36,34 +83,79 @@ declare const _default: import("nuxt/app").Plugin<{
|
|
|
36
83
|
resolveTranslations: (routeContext?: unknown) => Translations;
|
|
37
84
|
setTranslation: (key: TranslationKey, value: unknown) => void;
|
|
38
85
|
mergeTranslations: (newTranslations: Translations) => void;
|
|
39
|
-
switchLocaleRoute: (toLocale: string) =>
|
|
86
|
+
switchLocaleRoute: (toLocale: string) => string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric;
|
|
40
87
|
clearCache: () => void;
|
|
41
88
|
switchLocalePath: (toLocale: string) => string;
|
|
42
|
-
switchLocale: (toLocale: string) => Promise<
|
|
43
|
-
switchRoute: (route: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, toLocale?: string) => unknown
|
|
89
|
+
switchLocale: (toLocale: string) => Promise<boolean>;
|
|
90
|
+
switchRoute: (route: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, toLocale?: string) => Promise<unknown>;
|
|
44
91
|
localeRoute(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): RouteLocationResolved;
|
|
45
92
|
localePath(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): string;
|
|
46
|
-
setI18nRouteParams: (value: I18nRouteParams) => I18nRouteParams;
|
|
47
93
|
loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
48
94
|
setMissingHandler: (handler: MissingHandler | null) => void;
|
|
49
95
|
}> & import("nuxt/app").ObjectPlugin<{
|
|
50
|
-
|
|
96
|
+
i18n: {
|
|
97
|
+
helper: {
|
|
98
|
+
mergeTranslation(locale: string, routeName: string, newTranslations: Translations): Promise<void>;
|
|
99
|
+
};
|
|
100
|
+
getI18nConfig: () => ResolvedI18nConfig;
|
|
101
|
+
__micro: boolean;
|
|
102
|
+
i18nStrategy: PathStrategy;
|
|
103
|
+
getLocale: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric) => string;
|
|
104
|
+
getLocaleName: () => string | null;
|
|
105
|
+
defaultLocale: () => string;
|
|
106
|
+
getLocales: () => Locale[];
|
|
107
|
+
getRouteName: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric, _locale?: string) => string;
|
|
108
|
+
t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeContext?: unknown) => CleanTranslation;
|
|
109
|
+
ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeContext?: unknown) => string;
|
|
110
|
+
_t: (route: RouteLocationNormalizedLoaded) => TranslationFn<CleanTranslation>;
|
|
111
|
+
_ts: (route: RouteLocationNormalizedLoaded) => TranslationFn<string>;
|
|
112
|
+
tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string;
|
|
113
|
+
pluralFunc: PluralFunc;
|
|
114
|
+
pluralLocale: () => string;
|
|
115
|
+
tn: {
|
|
116
|
+
(value: number, options?: Intl.NumberFormatOptions): string;
|
|
117
|
+
(value: number, key: string, overrides?: Intl.NumberFormatOptions): string;
|
|
118
|
+
(value: number, key: string, locale: string, overrides?: Intl.NumberFormatOptions): string;
|
|
119
|
+
};
|
|
120
|
+
td: {
|
|
121
|
+
(value: Date | number | string, options?: Intl.DateTimeFormatOptions): string;
|
|
122
|
+
(value: Date | number | string, key: string, overrides?: Intl.DateTimeFormatOptions): string;
|
|
123
|
+
(value: Date | number | string, key: string, locale: string, overrides?: Intl.DateTimeFormatOptions): string;
|
|
124
|
+
};
|
|
125
|
+
tdr: (value: Date | number | string, options?: Intl.RelativeTimeFormatOptions) => string;
|
|
126
|
+
has: (key: TranslationKey, routeContext?: unknown) => boolean;
|
|
127
|
+
resolveTranslations: (routeContext?: unknown) => Translations;
|
|
128
|
+
setTranslation: (key: TranslationKey, value: unknown) => void;
|
|
129
|
+
mergeTranslations: (newTranslations: Translations) => void;
|
|
130
|
+
switchLocaleRoute: (toLocale: string) => string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric;
|
|
131
|
+
clearCache: () => void;
|
|
132
|
+
switchLocalePath: (toLocale: string) => string;
|
|
133
|
+
switchLocale: (toLocale: string) => Promise<boolean>;
|
|
134
|
+
switchRoute: (route: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, toLocale?: string) => Promise<unknown>;
|
|
135
|
+
localeRoute(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): RouteLocationResolved;
|
|
136
|
+
localePath(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): string;
|
|
137
|
+
loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
138
|
+
setMissingHandler: (handler: MissingHandler | null) => void;
|
|
139
|
+
};
|
|
140
|
+
defineI18nRoute: ReturnType<({ getLocale, mergeTranslations }: Pick<NuxtI18nPluginProvide, "getLocale" | "mergeTranslations">) => ({ locales }: DefineI18nRouteConfig) => Promise<void>>;
|
|
51
141
|
helper: {
|
|
52
|
-
mergeTranslation(locale: string, routeName: string, newTranslations: Translations
|
|
142
|
+
mergeTranslation(locale: string, routeName: string, newTranslations: Translations): Promise<void>;
|
|
53
143
|
};
|
|
54
|
-
|
|
144
|
+
getI18nConfig: () => ResolvedI18nConfig;
|
|
55
145
|
__micro: boolean;
|
|
56
146
|
i18nStrategy: PathStrategy;
|
|
57
147
|
getLocale: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric) => string;
|
|
58
148
|
getLocaleName: () => string | null;
|
|
59
|
-
defaultLocale: () => string
|
|
149
|
+
defaultLocale: () => string;
|
|
60
150
|
getLocales: () => Locale[];
|
|
61
|
-
getRouteName: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric,
|
|
151
|
+
getRouteName: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric, _locale?: string) => string;
|
|
62
152
|
t: (key: TranslationKey, params?: Params, defaultValue?: string | null, routeContext?: unknown) => CleanTranslation;
|
|
63
|
-
ts: (key: TranslationKey, params?: Params, defaultValue?: string,
|
|
153
|
+
ts: (key: TranslationKey, params?: Params, defaultValue?: string, routeContext?: unknown) => string;
|
|
64
154
|
_t: (route: RouteLocationNormalizedLoaded) => TranslationFn<CleanTranslation>;
|
|
65
155
|
_ts: (route: RouteLocationNormalizedLoaded) => TranslationFn<string>;
|
|
66
156
|
tc: (key: TranslationKey, count: number | Params, defaultValue?: string) => string;
|
|
157
|
+
pluralFunc: PluralFunc;
|
|
158
|
+
pluralLocale: () => string;
|
|
67
159
|
tn: {
|
|
68
160
|
(value: number, options?: Intl.NumberFormatOptions): string;
|
|
69
161
|
(value: number, key: string, overrides?: Intl.NumberFormatOptions): string;
|
|
@@ -79,14 +171,13 @@ declare const _default: import("nuxt/app").Plugin<{
|
|
|
79
171
|
resolveTranslations: (routeContext?: unknown) => Translations;
|
|
80
172
|
setTranslation: (key: TranslationKey, value: unknown) => void;
|
|
81
173
|
mergeTranslations: (newTranslations: Translations) => void;
|
|
82
|
-
switchLocaleRoute: (toLocale: string) =>
|
|
174
|
+
switchLocaleRoute: (toLocale: string) => string | import("vue-router").RouteLocationAsRelativeGeneric | import("vue-router").RouteLocationAsPathGeneric;
|
|
83
175
|
clearCache: () => void;
|
|
84
176
|
switchLocalePath: (toLocale: string) => string;
|
|
85
|
-
switchLocale: (toLocale: string) => Promise<
|
|
86
|
-
switchRoute: (route: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, toLocale?: string) => unknown
|
|
177
|
+
switchLocale: (toLocale: string) => Promise<boolean>;
|
|
178
|
+
switchRoute: (route: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, toLocale?: string) => Promise<unknown>;
|
|
87
179
|
localeRoute(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): RouteLocationResolved;
|
|
88
180
|
localePath(to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string): string;
|
|
89
|
-
setI18nRouteParams: (value: I18nRouteParams) => I18nRouteParams;
|
|
90
181
|
loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
91
182
|
setMissingHandler: (handler: MissingHandler | null) => void;
|
|
92
183
|
}>;
|
|
@@ -95,7 +186,7 @@ export interface PluginsInjections {
|
|
|
95
186
|
/** The active routing strategy, resolving locales to and from paths. */
|
|
96
187
|
$i18nStrategy: PathStrategy;
|
|
97
188
|
/** The resolved module configuration, as the runtime sees it. */
|
|
98
|
-
$getI18nConfig: () =>
|
|
189
|
+
$getI18nConfig: () => ResolvedI18nConfig;
|
|
99
190
|
/** Code of the active locale. Pass a route to read the locale that route belongs to. */
|
|
100
191
|
$getLocale: (route?: RouteLocationNormalizedLoaded | RouteLocationResolvedGeneric) => string;
|
|
101
192
|
/** The active locale's `displayName` from the config, or `null` when it has none. */
|
|
@@ -117,8 +208,8 @@ export interface PluginsInjections {
|
|
|
117
208
|
*/
|
|
118
209
|
$_t: (route: RouteLocationNormalizedLoaded) => TranslationFn<CleanTranslation>;
|
|
119
210
|
/**
|
|
120
|
-
* Like `$t`, but always returns a string:
|
|
121
|
-
*
|
|
211
|
+
* Like `$t`, but always returns a string: the value goes through `toString()`, so a nested
|
|
212
|
+
* object becomes `'[object Object]'`. Point the key at a leaf.
|
|
122
213
|
*/
|
|
123
214
|
$ts: TranslationFn<string>;
|
|
124
215
|
/** Bind `$ts` to a specific route. See `$_t`. */
|
|
@@ -128,6 +219,10 @@ export interface PluginsInjections {
|
|
|
128
219
|
* `count`.
|
|
129
220
|
*/
|
|
130
221
|
$tc: (key: TranslationKey, params: number | Params, defaultValue?: string) => string;
|
|
222
|
+
/** The plural rule `$tc` uses: `<i18n-t>` asks for it to pick a form from the raw translation. */
|
|
223
|
+
$pluralFunc: PluralFunc;
|
|
224
|
+
/** The tag `$tc` plurals by: the locale's `iso` when it has one, else its code. */
|
|
225
|
+
$pluralLocale: () => string;
|
|
131
226
|
/**
|
|
132
227
|
* Format a number with `Intl.NumberFormat` in the active locale. A key selects a named format
|
|
133
228
|
* from the config.
|
|
@@ -150,7 +245,8 @@ export interface PluginsInjections {
|
|
|
150
245
|
$tdr: (value: Date | number | string, options?: Intl.RelativeTimeFormatOptions) => string;
|
|
151
246
|
/**
|
|
152
247
|
* Whether a key resolves in the active locale. Use it to branch on optional copy instead of
|
|
153
|
-
* rendering a raw key.
|
|
248
|
+
* rendering a raw key. Like `$t`, it also sees the leaving page's keys during a same-locale
|
|
249
|
+
* page transition.
|
|
154
250
|
*/
|
|
155
251
|
$has: (key: string) => boolean;
|
|
156
252
|
/**
|
|
@@ -165,17 +261,39 @@ export interface PluginsInjections {
|
|
|
165
261
|
$setTranslation: (key: string, value: unknown) => void;
|
|
166
262
|
/** Merge translations into the active locale at runtime, overriding what is loaded. */
|
|
167
263
|
$mergeTranslations: (newTranslations: Translations) => void;
|
|
168
|
-
/**
|
|
264
|
+
/**
|
|
265
|
+
* The route object for the current page in another locale, without navigating, or a URL string
|
|
266
|
+
* for a locale on its own `baseUrl`. Under `trailingSlash` the object has `path` and `fullPath`,
|
|
267
|
+
* following the rule, with the `query` and `hash` as they are, and `router.push` or a link keep them.
|
|
268
|
+
*/
|
|
169
269
|
$switchLocaleRoute: (locale: string) => RouteLocationRaw;
|
|
170
270
|
/** The path of the current page in another locale, without navigating. */
|
|
171
271
|
$switchLocalePath: (locale: string) => string;
|
|
172
|
-
/**
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
272
|
+
/**
|
|
273
|
+
* Navigate to the current page in another locale. Under `no_prefix` and hash mode it loads the
|
|
274
|
+
* locale's translations before navigating; under `no_prefix` the route is replaced in place (no
|
|
275
|
+
* new history entry). An unknown locale is ignored.
|
|
276
|
+
* The call is async: `await` it to run code after the navigation. It resolves `true` when the
|
|
277
|
+
* locale's dictionary is active, `false` when it is not: the chunk failed to load (the current
|
|
278
|
+
* dictionary stays; call it again to retry) or a newer switch won.
|
|
279
|
+
*/
|
|
280
|
+
$switchLocale: (locale: string) => Promise<boolean>;
|
|
281
|
+
/**
|
|
282
|
+
* Navigate to another route, keeping the active locale or switching to `toLocale`. Async like
|
|
283
|
+
* `$switchLocale`.
|
|
284
|
+
*/
|
|
285
|
+
$switchRoute: (route: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, toLocale?: string) => Promise<void>;
|
|
286
|
+
/**
|
|
287
|
+
* Resolve a route in the given locale, or the active one. A plain object, safe to keep in state. When a param needs
|
|
288
|
+
* escaping it has `path`, `fullPath`, `query` and `hash` but no `name` or `params`: the path is what gives the router
|
|
289
|
+
* the encoded URL. For a locale on another domain `path` and `fullPath` are absolute, which the router cannot take:
|
|
290
|
+
* such a link goes through `<i18n-link>`, or `$localePath`.
|
|
291
|
+
*/
|
|
177
292
|
$localeRoute: (to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string) => RouteLocationResolved;
|
|
178
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* Resolve a path in the given locale, or the active one. A string with an `http(s):`, `mailto:`
|
|
295
|
+
* or `tel:` scheme comes back as is: do not pass user input as a link target unchecked.
|
|
296
|
+
*/
|
|
179
297
|
$localePath: (to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string) => string;
|
|
180
298
|
/**
|
|
181
299
|
* Set per-locale params for the current route, so a dynamic segment can differ per language.
|
|
@@ -186,6 +304,12 @@ export interface PluginsInjections {
|
|
|
186
304
|
$loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
187
305
|
/** Install a callback invoked for every unresolved key. Pass `null` to remove it. */
|
|
188
306
|
$setMissingHandler: (handler: MissingHandler | null) => void;
|
|
307
|
+
/**
|
|
308
|
+
* Drop every cached translation chunk and reload the current page's dictionary. The page
|
|
309
|
+
* keeps showing its current translations until the fresh ones arrive. Dev HMR calls it on
|
|
310
|
+
* every translation file change.
|
|
311
|
+
*/
|
|
312
|
+
$clearCache: () => void;
|
|
189
313
|
}
|
|
190
314
|
/**
|
|
191
315
|
* Helpers reachable through `useNuxtApp()` but deliberately absent from `useI18n()`.
|
|
@@ -200,6 +324,4 @@ export interface NuxtAppOnlyInjections {
|
|
|
200
324
|
* Merges into the active locale and re-applies when the locale changes.
|
|
201
325
|
*/
|
|
202
326
|
$defineI18nRoute: (routeDefinition: DefineI18nRouteConfig) => Promise<void>;
|
|
203
|
-
/** Drop every cached chunk, on the client and in the active dictionary. */
|
|
204
|
-
$clearCache: () => void;
|
|
205
327
|
}
|
|
@@ -1,160 +1,206 @@
|
|
|
1
|
-
import { isNoPrefixStrategy } from "@i18n-micro/core";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { escapeHtml, isNoPrefixStrategy, localeIsoMap } from "@i18n-micro/core";
|
|
2
|
+
import { detectLocaleFromAcceptLanguage } from "@i18n-micro/utils/accept-language";
|
|
3
|
+
import { PREMERGED_ROOT_PAGE } from "@i18n-micro/utils/merge-source";
|
|
4
|
+
import { hasProtocol } from "ufo";
|
|
5
|
+
import { shallowRef } from "vue";
|
|
6
|
+
import { useState } from "#app/composables/state";
|
|
4
7
|
import { plural } from "#build/i18n.plural.mjs";
|
|
5
|
-
import { createI18nStrategy,
|
|
6
|
-
import { createError, defineNuxtPlugin, navigateTo, useRouter, useRuntimeConfig } from "#imports";
|
|
7
|
-
import {
|
|
8
|
+
import { createI18nStrategy, domains } from "#build/i18n.strategy.mjs";
|
|
9
|
+
import { createError, defineNuxtPlugin, injectHead, navigateTo, useHead, useRouter, useRuntimeConfig } from "#imports";
|
|
10
|
+
import { usePageHead } from "../utils/page-head.js";
|
|
8
11
|
import { useI18nLocale } from "../composables/useI18nLocale.js";
|
|
9
|
-
import {
|
|
12
|
+
import { createI18nProvide, createNuxtI18nPluginApi } from "../utils/i18n-api.js";
|
|
13
|
+
import { useResolvedI18nConfig } from "../utils/i18n-config.js";
|
|
14
|
+
import { setupI18nNavigation } from "../utils/i18n-navigation.js";
|
|
15
|
+
import { formatterFor, NuxtI18n, NuxtTranslationLoader } from "../utils/nuxt-i18n.js";
|
|
16
|
+
import { ServerNuxtI18n } from "../utils/nuxt-i18n-server.js";
|
|
10
17
|
import { setI18nDevtoolsBridge } from "../devtools/bridge.js";
|
|
18
|
+
import { DEFAULT_SERVER_CACHE_SIZE } from "../utils/cache-keys.js";
|
|
11
19
|
import { translationStorage } from "../utils/storage.js";
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const i18nStrategy = createI18nStrategy(router);
|
|
16
|
-
const runtimeConfig = useRuntimeConfig();
|
|
17
|
-
const i18nConfig = resolveI18nConfigWithRuntimeOverrides(
|
|
18
|
-
getI18nConfig(),
|
|
19
|
-
runtimeConfig.public
|
|
20
|
-
);
|
|
21
|
-
translationStorage.configure({
|
|
22
|
-
maxSize: i18nConfig.cacheMaxSize ?? 0,
|
|
23
|
-
ttl: i18nConfig.cacheTtl ?? 0
|
|
24
|
-
});
|
|
25
|
-
const { locale: localeState, setLocale, getLocale, getEffectiveLocale, resolveInitialLocale, isValidLocale } = useI18nLocale();
|
|
26
|
-
const i18nRouteParams = useState("i18n-route-params", () => ({}));
|
|
27
|
-
const { resetPageHead } = useI18nHead();
|
|
28
|
-
const customMissingHandler = useState("i18n-missing-handler", () => null);
|
|
29
|
-
const i18n = new NuxtI18n({
|
|
20
|
+
const SWITCHER_LINK = /class="switcher-locale-([^"]+)" href="[^"]*"/g;
|
|
21
|
+
function createI18n(i18nConfig, missingHandler) {
|
|
22
|
+
return new (import.meta.server ? ServerNuxtI18n : NuxtI18n)({
|
|
30
23
|
plural,
|
|
31
|
-
missingWarn: i18nConfig.missingWarn
|
|
32
|
-
cacheMaxSize: i18nConfig.cacheMaxSize
|
|
33
|
-
getCustomMissingHandler: () =>
|
|
24
|
+
missingWarn: i18nConfig.missingWarn,
|
|
25
|
+
cacheMaxSize: i18nConfig.cacheMaxSize,
|
|
26
|
+
getCustomMissingHandler: () => missingHandler.value,
|
|
27
|
+
formatter: import.meta.server ? formatterFor(i18nConfig) : void 0,
|
|
34
28
|
numberFormats: i18nConfig.numberFormats,
|
|
35
|
-
datetimeFormats: i18nConfig.datetimeFormats
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const r = route ?? router.currentRoute.value;
|
|
39
|
-
return i18nStrategy.getCurrentLocale(r, getLocale() ?? null);
|
|
40
|
-
};
|
|
41
|
-
const getPluginRouteName = (route, locale) => {
|
|
42
|
-
return i18nStrategy.getPluginRouteName(route, locale);
|
|
43
|
-
};
|
|
44
|
-
i18n.setRouteContextResolver((route) => {
|
|
45
|
-
const resolvedRoute = route ?? router.currentRoute.value;
|
|
46
|
-
const locale = getCurrentLocale(resolvedRoute);
|
|
47
|
-
return {
|
|
48
|
-
locale,
|
|
49
|
-
routeName: getPluginRouteName(resolvedRoute, locale)
|
|
50
|
-
};
|
|
29
|
+
datetimeFormats: i18nConfig.datetimeFormats,
|
|
30
|
+
timeZone: i18nConfig.timeZone,
|
|
31
|
+
localeIso: localeIsoMap(i18nConfig.linkLocales ?? i18nConfig.locales)
|
|
51
32
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
const
|
|
56
|
-
apiBaseUrl: i18nConfig.apiBaseUrl
|
|
57
|
-
|
|
33
|
+
}
|
|
34
|
+
function createLoadOptions(nuxtApp, i18nConfig) {
|
|
35
|
+
const { baseURL, cdnURL } = useRuntimeConfig().app;
|
|
36
|
+
const options = {
|
|
37
|
+
apiBaseUrl: i18nConfig.apiBaseUrl,
|
|
38
|
+
// files can move to the CDN with the rest of `public/`. A dictionary only the route answers cannot
|
|
39
|
+
baseURL: i18nConfig.publicPayloads && cdnURL || baseURL,
|
|
58
40
|
apiBaseClientHost: i18nConfig.apiBaseClientHost,
|
|
59
41
|
dateBuild: i18nConfig.dateBuild,
|
|
60
|
-
routesLocaleLinks: i18nConfig.routesLocaleLinks
|
|
42
|
+
routesLocaleLinks: i18nConfig.routesLocaleLinks,
|
|
43
|
+
rootDelta: i18nConfig.rootDelta
|
|
61
44
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
const
|
|
45
|
+
if (import.meta.server) options.serverLoad = nuxtApp.ssrContext?.event?.context?.i18n?.load;
|
|
46
|
+
return options;
|
|
47
|
+
}
|
|
48
|
+
function resolveStartLocale({ nuxtApp, i18nConfig, i18nStrategy, renderLocale, initialRoute, locale, getCurrentLocale }) {
|
|
49
|
+
const { locale: localeState, getPreferredLocale, resolveInitialLocale, isValidLocale, validLocales } = locale;
|
|
50
|
+
const noPrefix = isNoPrefixStrategy(i18nConfig.strategy);
|
|
51
|
+
const shellLocale = () => {
|
|
52
|
+
const shell = i18nConfig.hashMode && i18nConfig.strategy === "prefix" && !nuxtApp.payload.serverRendered;
|
|
53
|
+
if (!shell || !i18nConfig.autoDetectLanguage || getPreferredLocale()) return void 0;
|
|
54
|
+
return detectLocaleFromAcceptLanguage(navigator.languages.join(","), validLocales);
|
|
55
|
+
};
|
|
56
|
+
const serverRequestLocale = () => renderLocale ?? nuxtApp.ssrContext?.event?.context?.i18n?.locale;
|
|
57
|
+
const requestLocale = import.meta.server ? serverRequestLocale() : shellLocale();
|
|
58
|
+
const preferredLocale = isValidLocale(localeState.value) ? localeState.value : requestLocale ?? getPreferredLocale();
|
|
59
|
+
const pathLocale = () => noPrefix ? i18nStrategy.getCurrentLocale(initialRoute, preferredLocale) : i18nStrategy.getLocaleFromPath(initialRoute.path);
|
|
68
60
|
const initialLocale = resolveInitialLocale({
|
|
69
|
-
route:
|
|
70
|
-
|
|
61
|
+
route: initialRoute,
|
|
62
|
+
urlLocale: i18nConfig.hashMode ? null : pathLocale(),
|
|
63
|
+
serverLocale: requestLocale,
|
|
64
|
+
preference: noPrefix ? preferredLocale ?? i18nConfig.defaultLocale : void 0,
|
|
71
65
|
getLocaleFromRoute: (r) => getCurrentLocale(r)
|
|
72
66
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
67
|
+
return initialLocale;
|
|
68
|
+
}
|
|
69
|
+
function rewriteSwitcherLinks(nuxtApp, api, params, resolveHref) {
|
|
70
|
+
nuxtApp.hooks.hook("app:rendered", ({ renderResult }) => {
|
|
71
|
+
if (!Object.keys(params.value ?? {}).length || !renderResult?.html?.includes('class="switcher-locale-')) return;
|
|
72
|
+
const codes = new Set(api.getLocales().map((locale) => locale.code));
|
|
73
|
+
renderResult.html = renderResult.html.replace(SWITCHER_LINK, (link, code) => {
|
|
74
|
+
if (!codes.has(code)) return link;
|
|
75
|
+
const path = api.switchLocalePath(code);
|
|
76
|
+
return `class="switcher-locale-${code}" href="${escapeHtml(hasProtocol(path) ? path : resolveHref(path))}"`;
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function createPageHeadDrop(pageHead) {
|
|
81
|
+
let headAdopted = import.meta.server;
|
|
82
|
+
let headToDrop = null;
|
|
83
|
+
if (import.meta.client) {
|
|
84
|
+
const stop = injectHead().hooks?.hook("dom:rendered", () => {
|
|
85
|
+
stop?.();
|
|
86
|
+
headAdopted = true;
|
|
87
|
+
if (pageHead.value === headToDrop) pageHead.value = null;
|
|
88
|
+
});
|
|
85
89
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return i18nStrategy.getRouteBaseName(selectedRoute, selectedLocale) ?? "";
|
|
90
|
+
return () => {
|
|
91
|
+
if (headAdopted) pageHead.value = null;
|
|
92
|
+
else headToDrop = pageHead.value;
|
|
90
93
|
};
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
i18nRouteParams,
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
94
|
+
}
|
|
95
|
+
export default defineNuxtPlugin({
|
|
96
|
+
name: "i18n-plugin-loader",
|
|
97
|
+
async setup(nuxtApp) {
|
|
98
|
+
const router = useRouter();
|
|
99
|
+
const i18nConfig = useResolvedI18nConfig(nuxtApp);
|
|
100
|
+
const i18nStrategy = createI18nStrategy(router, i18nConfig);
|
|
101
|
+
translationStorage.configure({
|
|
102
|
+
// the SSR copy is process-wide, so it is bounded like the payload cache
|
|
103
|
+
maxSize: i18nConfig.cacheMaxSize || (import.meta.server ? DEFAULT_SERVER_CACHE_SIZE : 0),
|
|
104
|
+
ttl: i18nConfig.cacheTtl
|
|
105
|
+
});
|
|
106
|
+
const locale = useI18nLocale();
|
|
107
|
+
const { locale: localeState, getPreferredLocale, isValidLocale } = locale;
|
|
108
|
+
const i18nRouteParams = useState("i18n-route-params", () => ({}));
|
|
109
|
+
const pageHead = usePageHead();
|
|
110
|
+
const customMissingHandler = shallowRef(null);
|
|
111
|
+
const i18n = createI18n(i18nConfig, customMissingHandler);
|
|
112
|
+
const islandLocale = nuxtApp.ssrContext?.islandContext?.props?.locale;
|
|
113
|
+
const renderLocale = isValidLocale(islandLocale) ? islandLocale : void 0;
|
|
114
|
+
const getCurrentLocale = (route) => {
|
|
115
|
+
if (!route && renderLocale) return renderLocale;
|
|
116
|
+
const r = route ?? router.currentRoute.value;
|
|
117
|
+
return i18nStrategy.getCurrentLocale(r, getPreferredLocale());
|
|
118
|
+
};
|
|
119
|
+
i18n.setRouteContextResolver((route) => {
|
|
120
|
+
const resolvedRoute = route ?? router.currentRoute.value;
|
|
121
|
+
const routeLocale = getCurrentLocale(resolvedRoute);
|
|
122
|
+
return { locale: routeLocale, routeName: i18nStrategy.getPluginRouteName(resolvedRoute, routeLocale) };
|
|
123
|
+
});
|
|
124
|
+
const prerender = import.meta.server && import.meta.prerender;
|
|
125
|
+
const loadOptions = createLoadOptions(nuxtApp, i18nConfig);
|
|
126
|
+
const onFailedRead = () => {
|
|
127
|
+
const context = nuxtApp.ssrContext?.event?.context.i18n;
|
|
128
|
+
if (context && !prerender) context.failedRead = true;
|
|
129
|
+
};
|
|
130
|
+
const loader = new NuxtTranslationLoader({ i18n, loadOptions, prerender, onFailedRead });
|
|
131
|
+
const initialRoute = router.currentRoute.value;
|
|
132
|
+
const initialLocale = resolveStartLocale({
|
|
133
|
+
nuxtApp,
|
|
116
134
|
i18nConfig,
|
|
117
|
-
|
|
135
|
+
i18nStrategy,
|
|
136
|
+
renderLocale,
|
|
137
|
+
initialRoute,
|
|
138
|
+
locale,
|
|
139
|
+
getCurrentLocale
|
|
118
140
|
});
|
|
119
|
-
|
|
120
|
-
router.beforeEach(async (to, from) => {
|
|
121
|
-
if (to.name !== from.name) {
|
|
122
|
-
i18nRouteParams.value = {};
|
|
123
|
-
resetPageHead();
|
|
124
|
-
}
|
|
125
|
-
const shouldSwitchContext = to.path !== from.path || isNoPrefixStrategy(i18nConfig.strategy);
|
|
126
|
-
if (!shouldSwitchContext) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
141
|
+
const initialRouteName = i18nStrategy.getPluginRouteName(initialRoute, initialLocale);
|
|
129
142
|
try {
|
|
130
|
-
|
|
131
|
-
const targetRouteName = getPluginRouteName(to, targetLocale);
|
|
132
|
-
let applied = true;
|
|
133
|
-
if (targetLocale !== i18n.getCurrentLocale() || targetRouteName !== i18n.getCurrentRouteName()) {
|
|
134
|
-
applied = await switchContext(targetLocale, targetRouteName);
|
|
135
|
-
} else {
|
|
136
|
-
loader.invalidatePendingSwitches();
|
|
137
|
-
}
|
|
138
|
-
if (applied && targetLocale && isValidLocale(targetLocale) && localeState.value !== targetLocale) {
|
|
139
|
-
setLocale(targetLocale);
|
|
140
|
-
}
|
|
143
|
+
await loader.switchContext(initialLocale, initialRouteName);
|
|
141
144
|
} catch (e) {
|
|
142
|
-
if (
|
|
145
|
+
if (process.env.NODE_ENV !== "production") console.error("[i18n] Initial load error:", e);
|
|
146
|
+
if (prerender) throw e;
|
|
147
|
+
throw createError({ statusCode: 404, statusMessage: "Page Not Found" });
|
|
143
148
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
i18n: void 0,
|
|
150
|
-
__micro: true
|
|
151
|
-
};
|
|
152
|
-
const $provideData = Object.fromEntries(Object.entries(provideData).map(([key, value]) => [`$${key}`, value]));
|
|
153
|
-
provideData.i18n = { ...provideData, ...$provideData };
|
|
154
|
-
return {
|
|
155
|
-
provide: {
|
|
156
|
-
...provideData,
|
|
157
|
-
getI18nConfig: () => i18nConfig
|
|
149
|
+
if (import.meta.server && !i18nConfig.noScripts && !nuxtApp.ssrContext?.event?.context?._nitro?.routeRules?.noScripts) {
|
|
150
|
+
const hint = (key, href) => ({ key, rel: "preload", as: "fetch", crossorigin: "anonymous", href });
|
|
151
|
+
const link = [hint("i18n-preload", translationStorage.clientUrl(initialLocale, initialRouteName, loadOptions))];
|
|
152
|
+
if (i18nConfig.rootDelta) link.push(hint("i18n-preload-root", translationStorage.clientUrl(initialLocale, PREMERGED_ROOT_PAGE, loadOptions)));
|
|
153
|
+
useHead({ link });
|
|
158
154
|
}
|
|
159
|
-
|
|
155
|
+
const hydrated = shallowRef(false);
|
|
156
|
+
nuxtApp.hooks.hookOnce("app:suspense:resolve", async () => {
|
|
157
|
+
hydrated.value = true;
|
|
158
|
+
if (!import.meta.client || !i18nConfig.hashMode) return;
|
|
159
|
+
const hashLocale = i18nStrategy.getLocaleFromPath(router.currentRoute.value.path);
|
|
160
|
+
if (hashLocale && hashLocale !== localeState.value) await api.provide.switchLocale(hashLocale);
|
|
161
|
+
});
|
|
162
|
+
const api = createNuxtI18nPluginApi({
|
|
163
|
+
i18n,
|
|
164
|
+
loader,
|
|
165
|
+
i18nStrategy,
|
|
166
|
+
// $getLocales lists the locales of other domains too: link targets
|
|
167
|
+
i18nConfig: domains ? { ...i18nConfig, locales: i18nConfig.linkLocales ?? i18nConfig.locales } : i18nConfig,
|
|
168
|
+
router,
|
|
169
|
+
locale,
|
|
170
|
+
getCurrentLocale,
|
|
171
|
+
i18nRouteParams,
|
|
172
|
+
navigateTo,
|
|
173
|
+
setMissingHandler: (handler) => {
|
|
174
|
+
customMissingHandler.value = handler;
|
|
175
|
+
},
|
|
176
|
+
// a ref: a link rendered without the hash gets it back when hydration ends
|
|
177
|
+
isHydrating: () => !hydrated.value && nuxtApp.isHydrating === true
|
|
178
|
+
});
|
|
179
|
+
if (import.meta.server) rewriteSwitcherLinks(nuxtApp, api.provide, i18nRouteParams, (path) => router.resolve(path).href);
|
|
180
|
+
if (import.meta.dev && import.meta.client) {
|
|
181
|
+
setI18nDevtoolsBridge({
|
|
182
|
+
i18n,
|
|
183
|
+
i18nConfig,
|
|
184
|
+
localeState
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const dropPageHead = createPageHeadDrop(pageHead);
|
|
188
|
+
setupI18nNavigation({
|
|
189
|
+
nuxtApp,
|
|
190
|
+
router,
|
|
191
|
+
i18n,
|
|
192
|
+
loader,
|
|
193
|
+
i18nConfig,
|
|
194
|
+
i18nStrategy,
|
|
195
|
+
locale,
|
|
196
|
+
api,
|
|
197
|
+
leavePage: () => {
|
|
198
|
+
i18nRouteParams.value = {};
|
|
199
|
+
dropPageHead();
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
const { provide, install } = createI18nProvide({ api, i18nConfig, router, i18nRouteParams });
|
|
203
|
+
install(nuxtApp);
|
|
204
|
+
return { provide };
|
|
205
|
+
}
|
|
160
206
|
});
|