nuxt-i18n-micro 1.101.2 → 2.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/README.md +21 -27
- package/dist/client/200.html +8 -8
- package/dist/client/404.html +8 -8
- package/dist/client/_nuxt/{DTIY11lm.js → BYEpoBUk.js} +1 -1
- package/dist/client/_nuxt/{T7szCJDf.js → CBxwnKtU.js} +1 -1
- package/dist/client/_nuxt/{Df3aIBNA.js → CQupjgaS.js} +1 -1
- package/dist/client/_nuxt/{s7GTWWQo.js → XZXfxmri.js} +33 -33
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/9577efa7-2d15-4fca-9d0d-3cd305cdd931.json +1 -0
- package/dist/client/_nuxt/error-404.Ba2SLv0l.css +1 -0
- package/dist/client/_nuxt/error-500.BqKd8Zt-.css +1 -0
- package/dist/client/index.html +8 -8
- package/dist/module.json +1 -1
- package/dist/module.mjs +96 -55
- package/dist/runtime/composables/useLocaleHead.d.ts +36 -33
- package/dist/runtime/composables/useLocaleHead.js +2 -13
- package/dist/runtime/plugins/01.plugin.d.ts +30 -0
- package/dist/runtime/plugins/01.plugin.js +52 -61
- package/dist/runtime/plugins/02.meta.js +19 -4
- package/dist/runtime/plugins/03.define.d.ts +3 -10
- package/dist/runtime/plugins/05.hooks.js +15 -7
- package/dist/runtime/server/plugins/watcher.dev.d.ts +2 -0
- package/dist/runtime/server/plugins/watcher.dev.js +60 -0
- package/dist/runtime/server/routes/get.js +62 -37
- package/dist/runtime/translation-server-middleware.js +11 -1
- package/dist/runtime/utils/route-utils.d.ts +9 -0
- package/dist/runtime/utils/route-utils.js +33 -0
- package/package.json +4 -4
- package/dist/client/_nuxt/builds/meta/48c4fe22-ef0c-4134-a6f0-f5d3d316c514.json +0 -1
- package/dist/client/_nuxt/error-404.B2VbLYbY.css +0 -1
- package/dist/client/_nuxt/error-500.DGwSTbEi.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"id":"
|
|
1
|
+
{"id":"9577efa7-2d15-4fca-9d0d-3cd305cdd931","timestamp":1761831387055}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"id":"9577efa7-2d15-4fca-9d0d-3cd305cdd931","timestamp":1761831387055,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.spotlight[data-v-f75a8935]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);bottom:-30vh;filter:blur(20vh);height:40vh}.gradient-border[data-v-f75a8935]{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:.5rem;position:relative}@media (prefers-color-scheme:light){.gradient-border[data-v-f75a8935]{background-color:#ffffff4d}.gradient-border[data-v-f75a8935]:before{background:linear-gradient(90deg,#e2e2e2,#e2e2e2 25%,#00dc82,#36e4da 75%,#0047e1)}}@media (prefers-color-scheme:dark){.gradient-border[data-v-f75a8935]{background-color:#1414144d}.gradient-border[data-v-f75a8935]:before{background:linear-gradient(90deg,#303030,#303030 25%,#00dc82,#36e4da 75%,#0047e1)}}.gradient-border[data-v-f75a8935]:before{background-size:400% auto;border-radius:.5rem;content:"";inset:0;-webkit-mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);mask:linear-gradient(#fff 0 0) content-box,linear-gradient(#fff 0 0);-webkit-mask-composite:xor;mask-composite:exclude;opacity:.5;padding:2px;position:absolute;transition:background-position .3s ease-in-out,opacity .2s ease-in-out;width:100%}.gradient-border[data-v-f75a8935]:hover:before{background-position:-50% 0;opacity:1}.fixed[data-v-f75a8935]{position:fixed}.left-0[data-v-f75a8935]{left:0}.right-0[data-v-f75a8935]{right:0}.z-10[data-v-f75a8935]{z-index:10}.z-20[data-v-f75a8935]{z-index:20}.grid[data-v-f75a8935]{display:grid}.mb-16[data-v-f75a8935]{margin-bottom:4rem}.mb-8[data-v-f75a8935]{margin-bottom:2rem}.max-w-520px[data-v-f75a8935]{max-width:520px}.min-h-screen[data-v-f75a8935]{min-height:100vh}.w-full[data-v-f75a8935]{width:100%}.flex[data-v-f75a8935]{display:flex}.cursor-pointer[data-v-f75a8935]{cursor:pointer}.place-content-center[data-v-f75a8935]{place-content:center}.items-center[data-v-f75a8935]{align-items:center}.justify-center[data-v-f75a8935]{justify-content:center}.overflow-hidden[data-v-f75a8935]{overflow:hidden}.bg-white[data-v-f75a8935]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-4[data-v-f75a8935]{padding-left:1rem;padding-right:1rem}.px-8[data-v-f75a8935]{padding-left:2rem;padding-right:2rem}.py-2[data-v-f75a8935]{padding-bottom:.5rem;padding-top:.5rem}.text-center[data-v-f75a8935]{text-align:center}.text-8xl[data-v-f75a8935]{font-size:6rem;line-height:1}.text-xl[data-v-f75a8935]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-f75a8935]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-f75a8935]{font-weight:300}.font-medium[data-v-f75a8935]{font-weight:500}.leading-tight[data-v-f75a8935]{line-height:1.25}.font-sans[data-v-f75a8935]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-f75a8935]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-f75a8935]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-f75a8935]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-f75a8935]{padding-left:0;padding-right:0}.sm\:px-6[data-v-f75a8935]{padding-left:1.5rem;padding-right:1.5rem}.sm\:py-3[data-v-f75a8935]{padding-bottom:.75rem;padding-top:.75rem}.sm\:text-4xl[data-v-f75a8935]{font-size:2.25rem;line-height:2.5rem}.sm\:text-xl[data-v-f75a8935]{font-size:1.25rem;line-height:1.75rem}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.spotlight[data-v-8bb04cde]{background:linear-gradient(45deg,#00dc82,#36e4da 50%,#0047e1);filter:blur(20vh)}.fixed[data-v-8bb04cde]{position:fixed}.-bottom-1\/2[data-v-8bb04cde]{bottom:-50%}.left-0[data-v-8bb04cde]{left:0}.right-0[data-v-8bb04cde]{right:0}.grid[data-v-8bb04cde]{display:grid}.mb-16[data-v-8bb04cde]{margin-bottom:4rem}.mb-8[data-v-8bb04cde]{margin-bottom:2rem}.h-1\/2[data-v-8bb04cde]{height:50%}.max-w-520px[data-v-8bb04cde]{max-width:520px}.min-h-screen[data-v-8bb04cde]{min-height:100vh}.place-content-center[data-v-8bb04cde]{place-content:center}.overflow-hidden[data-v-8bb04cde]{overflow:hidden}.bg-white[data-v-8bb04cde]{--un-bg-opacity:1;background-color:rgb(255 255 255/var(--un-bg-opacity))}.px-8[data-v-8bb04cde]{padding-left:2rem;padding-right:2rem}.text-center[data-v-8bb04cde]{text-align:center}.text-8xl[data-v-8bb04cde]{font-size:6rem;line-height:1}.text-xl[data-v-8bb04cde]{font-size:1.25rem;line-height:1.75rem}.text-black[data-v-8bb04cde]{--un-text-opacity:1;color:rgb(0 0 0/var(--un-text-opacity))}.font-light[data-v-8bb04cde]{font-weight:300}.font-medium[data-v-8bb04cde]{font-weight:500}.leading-tight[data-v-8bb04cde]{line-height:1.25}.font-sans[data-v-8bb04cde]{font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}.antialiased[data-v-8bb04cde]{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}@media (prefers-color-scheme:dark){.dark\:bg-black[data-v-8bb04cde]{--un-bg-opacity:1;background-color:rgb(0 0 0/var(--un-bg-opacity))}.dark\:text-white[data-v-8bb04cde]{--un-text-opacity:1;color:rgb(255 255 255/var(--un-text-opacity))}}@media (min-width:640px){.sm\:px-0[data-v-8bb04cde]{padding-left:0;padding-right:0}.sm\:text-4xl[data-v-8bb04cde]{font-size:2.25rem;line-height:2.5rem}}
|
package/dist/client/index.html
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<!DOCTYPE html><html><head><meta charset="utf-8">
|
|
2
2
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
3
3
|
<link rel="stylesheet" href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/entry.Cq9tULRb.css" crossorigin>
|
|
4
|
-
<link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
4
|
+
<link rel="modulepreload" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/XZXfxmri.js">
|
|
5
5
|
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/l5rcX3cq.js">
|
|
6
|
-
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.
|
|
7
|
-
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
8
|
-
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
9
|
-
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.
|
|
10
|
-
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
11
|
-
<script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/
|
|
12
|
-
<script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"
|
|
6
|
+
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-404.Ba2SLv0l.css">
|
|
7
|
+
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CQupjgaS.js">
|
|
8
|
+
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/CBxwnKtU.js">
|
|
9
|
+
<link rel="prefetch" as="style" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/error-500.BqKd8Zt-.css">
|
|
10
|
+
<link rel="prefetch" as="script" crossorigin href="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/BYEpoBUk.js">
|
|
11
|
+
<script type="module" src="/__NUXT_DEVTOOLS_I18N_BASE__/_nuxt/XZXfxmri.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" data-nuxt-data="nuxt-app" data-ssr="false" id="__NUXT_DATA__">[{"prerenderedAt":1,"serverRendered":2},1761831392702,false]</script>
|
|
12
|
+
<script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__NUXT_DEVTOOLS_I18N_BASE__/",buildId:"9577efa7-2d15-4fca-9d0d-3cd305cdd931",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -2,7 +2,6 @@ import path, { resolve, join } from 'node:path';
|
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import fs__default, { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
|
|
4
4
|
import { useNuxt, defineNuxtModule, useLogger, createResolver, addTemplate, addImportsDir, addPlugin, addServerHandler, addComponentsDir, addTypeTemplate, addPrerenderRoutes } from '@nuxt/kit';
|
|
5
|
-
import { watch } from 'chokidar';
|
|
6
5
|
import { isPrefixAndDefaultStrategy, isPrefixStrategy, isNoPrefixStrategy, isPrefixExceptDefaultStrategy, withPrefixStrategy } from 'nuxt-i18n-micro-core';
|
|
7
6
|
import { fileURLToPath } from 'node:url';
|
|
8
7
|
import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
|
|
@@ -189,39 +188,15 @@ function extractDefineI18nRouteData(content, _filePath) {
|
|
|
189
188
|
try {
|
|
190
189
|
const scriptContent = extractScriptContent(content);
|
|
191
190
|
if (!scriptContent) {
|
|
192
|
-
return
|
|
191
|
+
return null;
|
|
193
192
|
}
|
|
194
193
|
const configObject = findDefineI18nRouteConfig(scriptContent);
|
|
195
194
|
if (!configObject) {
|
|
196
|
-
return
|
|
197
|
-
}
|
|
198
|
-
let locales = null;
|
|
199
|
-
if (configObject.locales) {
|
|
200
|
-
if (Array.isArray(configObject.locales)) {
|
|
201
|
-
locales = configObject.locales.map((item) => {
|
|
202
|
-
if (typeof item === "string") {
|
|
203
|
-
return item;
|
|
204
|
-
} else if (typeof item === "object" && item !== null && item.code) {
|
|
205
|
-
return item.code;
|
|
206
|
-
}
|
|
207
|
-
return null;
|
|
208
|
-
}).filter((item) => item !== null);
|
|
209
|
-
} else if (typeof configObject.locales === "object") {
|
|
210
|
-
locales = Object.keys(configObject.locales).filter(
|
|
211
|
-
(key) => key !== "meta" && key !== "path" && key !== "title" && key !== "description"
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
let localeRoutes = null;
|
|
216
|
-
if (configObject.localeRoutes && typeof configObject.localeRoutes === "object") {
|
|
217
|
-
const isValid = Object.values(configObject.localeRoutes).every((value) => typeof value === "string");
|
|
218
|
-
if (isValid) {
|
|
219
|
-
localeRoutes = configObject.localeRoutes;
|
|
220
|
-
}
|
|
195
|
+
return null;
|
|
221
196
|
}
|
|
222
|
-
return
|
|
197
|
+
return configObject;
|
|
223
198
|
} catch {
|
|
224
|
-
return
|
|
199
|
+
return null;
|
|
225
200
|
}
|
|
226
201
|
}
|
|
227
202
|
const normalizePath = (routePath) => {
|
|
@@ -600,7 +575,14 @@ class PageManager {
|
|
|
600
575
|
...page,
|
|
601
576
|
children: this.createLocalizedChildren(originalChildren, page.path, localeCodes, true, false, parentLocale, { [firstLocale]: customPath }),
|
|
602
577
|
path: routePath,
|
|
603
|
-
name: routeName
|
|
578
|
+
name: routeName,
|
|
579
|
+
alias: [],
|
|
580
|
+
// remove alias to prevent infinite recursion
|
|
581
|
+
meta: {
|
|
582
|
+
...page.meta,
|
|
583
|
+
alias: []
|
|
584
|
+
// remove alias to prevent infinite recursion
|
|
585
|
+
}
|
|
604
586
|
};
|
|
605
587
|
}
|
|
606
588
|
buildLocalizedRouteName(baseName, locale, modifyName, forceLocaleSuffixOrCustom = false) {
|
|
@@ -709,6 +691,7 @@ const module = defineNuxtModule({
|
|
|
709
691
|
disablePageLocales: false,
|
|
710
692
|
disableWatcher: false,
|
|
711
693
|
disableUpdater: false,
|
|
694
|
+
// experimental kept in runtimeConfig only to avoid type drift here
|
|
712
695
|
noPrefixRedirect: false,
|
|
713
696
|
includeDefaultLocaleRoute: void 0,
|
|
714
697
|
fallbackLocale: void 0,
|
|
@@ -749,19 +732,29 @@ const module = defineNuxtModule({
|
|
|
749
732
|
const localeManager = new LocaleManager(options, rootDirs);
|
|
750
733
|
const routeLocales = {};
|
|
751
734
|
const globalLocaleRoutes = {};
|
|
735
|
+
const routeDisableMeta = {};
|
|
752
736
|
const pageFiles = await globby("pages/**/*.vue", { cwd: nuxt.options.rootDir });
|
|
753
737
|
for (const pageFile of pageFiles) {
|
|
754
738
|
const fullPath = join(nuxt.options.rootDir, pageFile);
|
|
755
739
|
try {
|
|
756
740
|
const fileContent = readFileSync(fullPath, "utf-8");
|
|
757
|
-
const
|
|
741
|
+
const config = extractDefineI18nRouteData(fileContent, fullPath);
|
|
742
|
+
if (!config) continue;
|
|
743
|
+
const { locales: extractedLocales, localeRoutes, disableMeta } = config;
|
|
758
744
|
const routePath = pageFile.replace(/^pages\//, "/").replace(/\/index\.vue$/, "").replace(/\.vue$/, "").replace(/\/$/, "") || "/";
|
|
759
745
|
if (extractedLocales) {
|
|
760
|
-
|
|
746
|
+
if (Array.isArray(extractedLocales)) {
|
|
747
|
+
routeLocales[routePath] = extractedLocales;
|
|
748
|
+
} else if (typeof extractedLocales === "object") {
|
|
749
|
+
routeLocales[routePath] = Object.keys(extractedLocales);
|
|
750
|
+
}
|
|
761
751
|
}
|
|
762
752
|
if (localeRoutes) {
|
|
763
753
|
globalLocaleRoutes[routePath] = localeRoutes;
|
|
764
754
|
}
|
|
755
|
+
if (disableMeta !== void 0) {
|
|
756
|
+
routeDisableMeta[routePath] = disableMeta;
|
|
757
|
+
}
|
|
765
758
|
} catch {
|
|
766
759
|
}
|
|
767
760
|
}
|
|
@@ -782,9 +775,6 @@ const module = defineNuxtModule({
|
|
|
782
775
|
localeCookie: options.localeCookie ?? "user-locale",
|
|
783
776
|
autoDetectPath: options.autoDetectPath ?? "/",
|
|
784
777
|
strategy: options.strategy ?? "prefix_except_default",
|
|
785
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
786
|
-
// @ts-ignore
|
|
787
|
-
routesLocaleLinks: options.routesLocaleLinks ?? {},
|
|
788
778
|
dateBuild: Date.now(),
|
|
789
779
|
hashMode: nuxt.options?.router?.options?.hashMode ?? false,
|
|
790
780
|
apiBaseUrl,
|
|
@@ -795,8 +785,14 @@ const module = defineNuxtModule({
|
|
|
795
785
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
796
786
|
// @ts-ignore
|
|
797
787
|
routeLocales,
|
|
788
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
789
|
+
// @ts-ignore
|
|
790
|
+
routeDisableMeta,
|
|
798
791
|
experimental: {
|
|
799
|
-
i18nPreviousPageFallback: options.experimental?.i18nPreviousPageFallback ?? false
|
|
792
|
+
i18nPreviousPageFallback: options.experimental?.i18nPreviousPageFallback ?? false,
|
|
793
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
794
|
+
// @ts-ignore
|
|
795
|
+
hmr: options.experimental?.hmr ?? true
|
|
800
796
|
}
|
|
801
797
|
};
|
|
802
798
|
if (typeof options.customRegexMatcher !== "undefined") {
|
|
@@ -813,7 +809,10 @@ const module = defineNuxtModule({
|
|
|
813
809
|
// @ts-ignore
|
|
814
810
|
fallbackLocale: options.fallbackLocale ?? void 0,
|
|
815
811
|
translationDir: options.translationDir ?? "locales",
|
|
816
|
-
customRegexMatcher: options.customRegexMatcher
|
|
812
|
+
customRegexMatcher: options.customRegexMatcher,
|
|
813
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
814
|
+
// @ts-ignore
|
|
815
|
+
routesLocaleLinks: options.routesLocaleLinks ?? {}
|
|
817
816
|
};
|
|
818
817
|
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
819
818
|
if (process.env && process.env.TEST) {
|
|
@@ -873,12 +872,66 @@ const module = defineNuxtModule({
|
|
|
873
872
|
pathPrefix: false,
|
|
874
873
|
extensions: ["vue"]
|
|
875
874
|
});
|
|
875
|
+
if (nuxt.options.dev && (options.experimental?.hmr ?? true)) {
|
|
876
|
+
const translationsDir = join(nuxt.options.rootDir, options.translationDir || "locales");
|
|
877
|
+
const files = await globby(["**/*.json"], { cwd: translationsDir, absolute: true });
|
|
878
|
+
const tpl = addTemplate({
|
|
879
|
+
filename: "i18n-hmr-plugin.mjs",
|
|
880
|
+
write: true,
|
|
881
|
+
getContents: () => generateHmrPlugin(files.map((f) => f.replace(/\\/g, "/")))
|
|
882
|
+
});
|
|
883
|
+
addPlugin({
|
|
884
|
+
src: tpl.dst,
|
|
885
|
+
mode: "client",
|
|
886
|
+
name: "i18n-hmr-plugin",
|
|
887
|
+
order: 10
|
|
888
|
+
});
|
|
889
|
+
}
|
|
876
890
|
if (options.types) {
|
|
877
891
|
addTypeTemplate({
|
|
878
892
|
filename: "types/i18n-plugin.d.ts",
|
|
879
893
|
getContents: () => generateI18nTypes()
|
|
880
894
|
});
|
|
881
895
|
}
|
|
896
|
+
function generateHmrPlugin(files) {
|
|
897
|
+
const accepts = files.map((file) => {
|
|
898
|
+
const isPage = /\/pages\//.test(file);
|
|
899
|
+
let pageName = "";
|
|
900
|
+
let locale = "";
|
|
901
|
+
if (isPage) {
|
|
902
|
+
const m = /\/pages\/([^/]+)\/([^/]+)\.json$/.exec(file);
|
|
903
|
+
pageName = m?.[1] || "";
|
|
904
|
+
locale = m?.[2] || "";
|
|
905
|
+
} else {
|
|
906
|
+
const m = /\/([^/]+)\.json$/.exec(file);
|
|
907
|
+
locale = m?.[1] || "";
|
|
908
|
+
}
|
|
909
|
+
return `
|
|
910
|
+
if (import.meta.hot) {
|
|
911
|
+
import.meta.hot.accept('${file}', async (mod) => {
|
|
912
|
+
const nuxtApp = useNuxtApp()
|
|
913
|
+
const data = (mod && typeof mod === 'object' && Object.prototype.hasOwnProperty.call(mod, 'default'))
|
|
914
|
+
? mod.default
|
|
915
|
+
: mod
|
|
916
|
+
try {
|
|
917
|
+
${isPage ? `await nuxtApp.$loadPageTranslations('${locale}', '${pageName}', data)` : `await nuxtApp.$loadTranslations('${locale}', data)`}
|
|
918
|
+
console.log('[i18n HMR] Translations reloaded:', '${isPage ? "page" : "global"}', '${locale}'${isPage ? `, '${pageName}'` : ""})
|
|
919
|
+
}
|
|
920
|
+
catch (e) {
|
|
921
|
+
console.warn('[i18n HMR] Failed to reload translations for', '${file}', e)
|
|
922
|
+
}
|
|
923
|
+
})
|
|
924
|
+
}
|
|
925
|
+
`.trim();
|
|
926
|
+
}).join("\n");
|
|
927
|
+
return `
|
|
928
|
+
import { defineNuxtPlugin, useNuxtApp } from '#imports'
|
|
929
|
+
|
|
930
|
+
export default defineNuxtPlugin(() => {
|
|
931
|
+
${accepts}
|
|
932
|
+
})
|
|
933
|
+
`.trim();
|
|
934
|
+
}
|
|
882
935
|
nuxt.hook("pages:resolved", (pages) => {
|
|
883
936
|
const prerenderRoutes = [];
|
|
884
937
|
const routeRules = nuxt.options.routeRules || {};
|
|
@@ -1035,24 +1088,12 @@ const module = defineNuxtModule({
|
|
|
1035
1088
|
}
|
|
1036
1089
|
}
|
|
1037
1090
|
});
|
|
1038
|
-
|
|
1039
|
-
nuxt.
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
const watcherEvent = async (path2) => {
|
|
1045
|
-
await watcher.close();
|
|
1046
|
-
logger.log("\u21BB update store item: " + path2);
|
|
1047
|
-
nuxt.callHook("restart");
|
|
1048
|
-
};
|
|
1049
|
-
const watcher = watch(translationPath, { depth: 2, persistent: true }).on("change", watcherEvent);
|
|
1050
|
-
nuxt.hook("close", () => {
|
|
1051
|
-
watcher.close();
|
|
1052
|
-
});
|
|
1053
|
-
}
|
|
1054
|
-
});
|
|
1055
|
-
}
|
|
1091
|
+
nuxt.hook("nitro:config", (nitroConfig) => {
|
|
1092
|
+
if (nuxt.options.dev && (options.experimental?.hmr ?? true) && !options.disableUpdater) {
|
|
1093
|
+
nitroConfig.plugins = nitroConfig.plugins || [];
|
|
1094
|
+
nitroConfig.plugins.push(resolver.resolve("./runtime/server/plugins/watcher.dev"));
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1056
1097
|
nuxt.hook("prerender:routes", async (prerenderRoutes) => {
|
|
1057
1098
|
if (isNoPrefixStrategy(options.strategy)) {
|
|
1058
1099
|
return;
|
|
@@ -22,37 +22,40 @@ export declare const useLocaleHead: ({ addDirAttribute, identifierAttribute, add
|
|
|
22
22
|
identifierAttribute?: string | undefined;
|
|
23
23
|
addSeoAttributes?: boolean | undefined;
|
|
24
24
|
baseUrl?: string | undefined;
|
|
25
|
-
}) =>
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
25
|
+
}) => {
|
|
26
|
+
metaObject: import("vue").Ref<{
|
|
27
|
+
htmlAttrs: {
|
|
28
|
+
lang?: string | undefined;
|
|
29
|
+
dir?: "ltr" | "rtl" | "auto" | undefined;
|
|
30
|
+
};
|
|
31
|
+
link: {
|
|
32
|
+
[x: string]: string | undefined;
|
|
33
|
+
rel: string;
|
|
34
|
+
href: string;
|
|
35
|
+
hreflang?: string | undefined;
|
|
36
|
+
}[];
|
|
37
|
+
meta: {
|
|
38
|
+
[x: string]: string;
|
|
39
|
+
property: string;
|
|
40
|
+
content: string;
|
|
41
|
+
}[];
|
|
42
|
+
}, MetaObject | {
|
|
43
|
+
htmlAttrs: {
|
|
44
|
+
lang?: string | undefined;
|
|
45
|
+
dir?: "ltr" | "rtl" | "auto" | undefined;
|
|
46
|
+
};
|
|
47
|
+
link: {
|
|
48
|
+
[x: string]: string | undefined;
|
|
49
|
+
rel: string;
|
|
50
|
+
href: string;
|
|
51
|
+
hreflang?: string | undefined;
|
|
52
|
+
}[];
|
|
53
|
+
meta: {
|
|
54
|
+
[x: string]: string;
|
|
55
|
+
property: string;
|
|
56
|
+
content: string;
|
|
57
|
+
}[];
|
|
58
|
+
}>;
|
|
59
|
+
updateMeta: () => void;
|
|
60
|
+
};
|
|
58
61
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { joinURL, parseURL, withQuery } from "ufo";
|
|
2
2
|
import { isPrefixExceptDefaultStrategy, isNoPrefixStrategy } from "nuxt-i18n-micro-core";
|
|
3
|
-
import { unref, useRoute, useRuntimeConfig,
|
|
3
|
+
import { unref, useRoute, useRuntimeConfig, ref, useNuxtApp } from "#imports";
|
|
4
4
|
import { findAllowedLocalesForRoute } from "../utils/route-utils.js";
|
|
5
5
|
export const useLocaleHead = ({ addDirAttribute = true, identifierAttribute = "id", addSeoAttributes = true, baseUrl = "/" } = {}) => {
|
|
6
6
|
const metaObject = ref({
|
|
@@ -101,16 +101,5 @@ export const useLocaleHead = ({ addDirAttribute = true, identifierAttribute = "i
|
|
|
101
101
|
metaObject.value.meta = [ogLocaleMeta, ogUrlMeta, ...alternateOgLocalesMeta];
|
|
102
102
|
metaObject.value.link = [canonicalLink, ...alternateLinks];
|
|
103
103
|
}
|
|
104
|
-
|
|
105
|
-
const route = useRoute();
|
|
106
|
-
const stop = watch(
|
|
107
|
-
() => route.fullPath,
|
|
108
|
-
() => updateMeta(),
|
|
109
|
-
{ immediate: true }
|
|
110
|
-
);
|
|
111
|
-
onUnmounted(() => stop());
|
|
112
|
-
} else {
|
|
113
|
-
updateMeta();
|
|
114
|
-
}
|
|
115
|
-
return metaObject;
|
|
104
|
+
return { metaObject, updateMeta };
|
|
116
105
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { RouteLocationNormalizedLoaded, RouteLocationRaw, RouteLocationResolved, RouteLocationResolvedGeneric, RouteLocationNamedRaw } from 'vue-router';
|
|
2
|
+
import { useTranslationHelper } from 'nuxt-i18n-micro-core';
|
|
2
3
|
import type { Locale, I18nRouteParams, Params, Translations, CleanTranslation } from 'nuxt-i18n-micro-types';
|
|
3
4
|
declare const _default: import("nuxt/app").Plugin<{
|
|
4
5
|
i18n: undefined;
|
|
@@ -28,6 +29,20 @@ declare const _default: import("nuxt/app").Plugin<{
|
|
|
28
29
|
localePath: (to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string) => string;
|
|
29
30
|
setI18nRouteParams: (value: I18nRouteParams) => I18nRouteParams;
|
|
30
31
|
loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
32
|
+
helper: {
|
|
33
|
+
hasCache(locale: string, page: string): boolean;
|
|
34
|
+
getCache(locale: string, routeName: string): Map<string, unknown> | undefined;
|
|
35
|
+
setCache(locale: string, routeName: string, cache: Map<string, Translations | unknown>): void;
|
|
36
|
+
mergeTranslation(locale: string, routeName: string, newTranslations: Translations, force?: boolean): void;
|
|
37
|
+
mergeGlobalTranslation(locale: string, newTranslations: Translations, force?: boolean): void;
|
|
38
|
+
hasGeneralTranslation(locale: string): boolean;
|
|
39
|
+
hasPageTranslation(locale: string, routeName: string): boolean;
|
|
40
|
+
hasTranslation: (locale: string, key: string) => boolean;
|
|
41
|
+
getTranslation: <T = unknown>(locale: string, routeName: string, key: string) => T | null;
|
|
42
|
+
loadPageTranslations(locale: string, routeName: string, translations: Translations): Promise<void>;
|
|
43
|
+
loadTranslations(locale: string, translations: Translations): Promise<void>;
|
|
44
|
+
clearCache(): void;
|
|
45
|
+
};
|
|
31
46
|
}> & import("nuxt/app").ObjectPlugin<{
|
|
32
47
|
i18n: undefined;
|
|
33
48
|
__micro: boolean;
|
|
@@ -56,6 +71,20 @@ declare const _default: import("nuxt/app").Plugin<{
|
|
|
56
71
|
localePath: (to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string) => string;
|
|
57
72
|
setI18nRouteParams: (value: I18nRouteParams) => I18nRouteParams;
|
|
58
73
|
loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
74
|
+
helper: {
|
|
75
|
+
hasCache(locale: string, page: string): boolean;
|
|
76
|
+
getCache(locale: string, routeName: string): Map<string, unknown> | undefined;
|
|
77
|
+
setCache(locale: string, routeName: string, cache: Map<string, Translations | unknown>): void;
|
|
78
|
+
mergeTranslation(locale: string, routeName: string, newTranslations: Translations, force?: boolean): void;
|
|
79
|
+
mergeGlobalTranslation(locale: string, newTranslations: Translations, force?: boolean): void;
|
|
80
|
+
hasGeneralTranslation(locale: string): boolean;
|
|
81
|
+
hasPageTranslation(locale: string, routeName: string): boolean;
|
|
82
|
+
hasTranslation: (locale: string, key: string) => boolean;
|
|
83
|
+
getTranslation: <T = unknown>(locale: string, routeName: string, key: string) => T | null;
|
|
84
|
+
loadPageTranslations(locale: string, routeName: string, translations: Translations): Promise<void>;
|
|
85
|
+
loadTranslations(locale: string, translations: Translations): Promise<void>;
|
|
86
|
+
clearCache(): void;
|
|
87
|
+
};
|
|
59
88
|
}>;
|
|
60
89
|
export default _default;
|
|
61
90
|
export interface PluginsInjections {
|
|
@@ -83,4 +112,5 @@ export interface PluginsInjections {
|
|
|
83
112
|
$localePath: (to: RouteLocationNamedRaw | RouteLocationResolvedGeneric | string, locale?: string) => string;
|
|
84
113
|
$setI18nRouteParams: (value: I18nRouteParams) => I18nRouteParams;
|
|
85
114
|
$loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
|
|
115
|
+
helper: ReturnType<typeof useTranslationHelper>;
|
|
86
116
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useTranslationHelper, interpolate, isNoPrefixStrategy, RouteService, FormatService } from "nuxt-i18n-micro-core";
|
|
2
|
-
import { useRouter, useCookie,
|
|
2
|
+
import { useRouter, useCookie, unref, navigateTo, defineNuxtPlugin, useRuntimeConfig, createError } from "#imports";
|
|
3
|
+
import { useState } from "#app";
|
|
3
4
|
import { plural } from "#build/i18n.plural.mjs";
|
|
4
|
-
const i18nHelper = useTranslationHelper();
|
|
5
5
|
const isDev = process.env.NODE_ENV !== "production";
|
|
6
6
|
export default defineNuxtPlugin(async (nuxtApp) => {
|
|
7
7
|
const config = useRuntimeConfig();
|
|
@@ -9,6 +9,17 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
9
9
|
const apiBaseUrl = i18nConfig.apiBaseUrl ?? "_locales";
|
|
10
10
|
const router = useRouter();
|
|
11
11
|
const runtimeConfig = useRuntimeConfig();
|
|
12
|
+
const generalLocaleCache = useState("i18n-general-cache", () => ({}));
|
|
13
|
+
const routeLocaleCache = useState("i18n-route-cache", () => ({}));
|
|
14
|
+
const dynamicTranslationsCaches = useState("i18n-dynamic-caches", () => []);
|
|
15
|
+
const serverTranslationCache = useState("i18n-server-cache", () => ({}));
|
|
16
|
+
const translationCaches = {
|
|
17
|
+
generalLocaleCache,
|
|
18
|
+
routeLocaleCache,
|
|
19
|
+
dynamicTranslationsCaches,
|
|
20
|
+
serverTranslationCache
|
|
21
|
+
};
|
|
22
|
+
const i18nHelper = useTranslationHelper(translationCaches);
|
|
12
23
|
let hashLocaleDefault = null;
|
|
13
24
|
let noPrefixDefault = null;
|
|
14
25
|
if (i18nConfig.hashMode) {
|
|
@@ -39,75 +50,56 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
39
50
|
previousPageInfo.value = null;
|
|
40
51
|
}
|
|
41
52
|
});
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
if (!i18nHelper.hasPageTranslation(locale, routeName)) {
|
|
45
|
-
let fRouteName = routeName;
|
|
46
|
-
if (i18nConfig.routesLocaleLinks && fRouteName && i18nConfig.routesLocaleLinks[fRouteName]) {
|
|
47
|
-
const newRouteName = i18nConfig.routesLocaleLinks[fRouteName];
|
|
48
|
-
if (newRouteName) {
|
|
49
|
-
fRouteName = newRouteName;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
if (!fRouteName || fRouteName === "") {
|
|
53
|
-
console.warn(`[nuxt-i18n-next] The page name is missing in the path: ${path}. Please ensure that definePageMeta({ name: 'pageName' }) is set.`);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const url = `/${apiBaseUrl}/${fRouteName}/${locale}/data.json`.replace(/\/{2,}/g, "/");
|
|
57
|
-
const data = await $fetch(url, {
|
|
58
|
-
baseURL: runtimeConfig.app.baseURL,
|
|
59
|
-
params: {
|
|
60
|
-
v: i18nConfig.dateBuild
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
await i18nHelper.loadPageTranslations(locale, routeName, data ?? {});
|
|
64
|
-
}
|
|
65
|
-
} catch (_error) {
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
async function loadGlobalTranslations(to) {
|
|
53
|
+
async function loadPageAndGlobalTranslations(to) {
|
|
69
54
|
let locale = routeService.getCurrentLocale(to);
|
|
70
55
|
if (i18nConfig.hashMode) {
|
|
71
|
-
locale = await nuxtApp.runWithContext(() => {
|
|
72
|
-
return useCookie("hash-locale", { default: () => locale }).value;
|
|
73
|
-
});
|
|
56
|
+
locale = await nuxtApp.runWithContext(() => useCookie("hash-locale", { default: () => locale }).value);
|
|
74
57
|
}
|
|
75
58
|
if (isNoPrefixStrategy(i18nConfig.strategy)) {
|
|
76
|
-
locale = await nuxtApp.runWithContext(() => {
|
|
77
|
-
|
|
78
|
-
|
|
59
|
+
locale = await nuxtApp.runWithContext(() => useCookie("no-prefix-locale", { default: () => locale }).value);
|
|
60
|
+
}
|
|
61
|
+
const routeName = routeService.getRouteName(to, locale);
|
|
62
|
+
if (!routeName) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (i18nHelper.hasPageTranslation(locale, routeName)) {
|
|
66
|
+
if (isDev) {
|
|
67
|
+
console.log(`[DEBUG] Cache HIT for '${locale}:${routeName}'. Skipping fetch.`);
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
79
70
|
}
|
|
80
|
-
|
|
81
|
-
|
|
71
|
+
const url = `/${apiBaseUrl}/${routeName}/${locale}/data.json`.replace(/\/{2,}/g, "/");
|
|
72
|
+
try {
|
|
82
73
|
const data = await $fetch(url, {
|
|
83
74
|
baseURL: runtimeConfig.app.baseURL,
|
|
84
|
-
params: {
|
|
85
|
-
v: i18nConfig.dateBuild
|
|
86
|
-
}
|
|
75
|
+
params: { v: i18nConfig.dateBuild }
|
|
87
76
|
});
|
|
88
|
-
await i18nHelper.
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
77
|
+
await i18nHelper.loadPageTranslations(locale, routeName, data ?? {});
|
|
78
|
+
} catch (e) {
|
|
79
|
+
if (isDev) {
|
|
80
|
+
console.error(`[i18n] Failed to load translations for ${routeName}/${locale}`, e);
|
|
81
|
+
}
|
|
82
|
+
throw createError({ statusCode: 404, statusMessage: "Page Not Found" });
|
|
94
83
|
}
|
|
95
84
|
}
|
|
96
85
|
router.beforeEach(async (to, from, next) => {
|
|
97
|
-
if (to.path
|
|
98
|
-
if (
|
|
99
|
-
|
|
100
|
-
const fromRouteName = routeService.getRouteName(from, fromLocale);
|
|
101
|
-
previousPageInfo.value = { locale: fromLocale, routeName: fromRouteName };
|
|
102
|
-
console.log(`Saved previous page info for cleanup: ${fromRouteName}`);
|
|
103
|
-
}
|
|
104
|
-
await loadGlobalTranslations(to);
|
|
86
|
+
if (to.path === from.path && !isNoPrefixStrategy(i18nConfig.strategy)) {
|
|
87
|
+
if (next) next();
|
|
88
|
+
return;
|
|
105
89
|
}
|
|
106
|
-
if (
|
|
107
|
-
|
|
90
|
+
if (import.meta.client && enablePreviousPageFallback) {
|
|
91
|
+
const fromLocale = routeService.getCurrentLocale(from);
|
|
92
|
+
const fromRouteName = routeService.getRouteName(from, fromLocale);
|
|
93
|
+
previousPageInfo.value = { locale: fromLocale, routeName: fromRouteName };
|
|
108
94
|
}
|
|
95
|
+
try {
|
|
96
|
+
await loadPageAndGlobalTranslations(to);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
console.error("[i18n] Error loading translations:", e);
|
|
99
|
+
}
|
|
100
|
+
if (next) next();
|
|
109
101
|
});
|
|
110
|
-
await
|
|
102
|
+
await loadPageAndGlobalTranslations(router.currentRoute.value);
|
|
111
103
|
const provideData = {
|
|
112
104
|
i18n: void 0,
|
|
113
105
|
__micro: true,
|
|
@@ -134,9 +126,6 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
134
126
|
console.log(`Using fallback translation from previous route: ${prev.routeName} -> ${key}`);
|
|
135
127
|
}
|
|
136
128
|
}
|
|
137
|
-
if (!value) {
|
|
138
|
-
value = i18nHelper.getTranslation(locale, "", key);
|
|
139
|
-
}
|
|
140
129
|
if (!value) {
|
|
141
130
|
if (isDev && import.meta.client) {
|
|
142
131
|
console.warn(`Not found '${key}' key in '${locale}' locale messages for route '${routeName}'.`);
|
|
@@ -243,7 +232,9 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
|
|
243
232
|
},
|
|
244
233
|
loadPageTranslations: async (locale, routeName, translations) => {
|
|
245
234
|
await i18nHelper.loadPageTranslations(locale, routeName, translations);
|
|
246
|
-
}
|
|
235
|
+
},
|
|
236
|
+
helper: i18nHelper
|
|
237
|
+
// Оставляем helper, он может быть полезен для продвинутых пользователей
|
|
247
238
|
};
|
|
248
239
|
const $provideData = Object.fromEntries(
|
|
249
240
|
Object.entries(provideData).map(([key, value]) => [`$${key}`, value])
|
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
import { useLocaleHead } from "../composables/useLocaleHead.js";
|
|
2
|
-
import { useRequestURL, useHead, defineNuxtPlugin, useRuntimeConfig } from "#imports";
|
|
2
|
+
import { useRequestURL, useHead, defineNuxtPlugin, useRuntimeConfig, useRoute, watch } from "#imports";
|
|
3
|
+
import { isMetaDisabledForRoute } from "../utils/route-utils.js";
|
|
3
4
|
const host = process.env.HOST ?? "localhost";
|
|
4
5
|
const port = process.env.PORT ?? "host";
|
|
5
|
-
export default defineNuxtPlugin((
|
|
6
|
+
export default defineNuxtPlugin((nuxtApp) => {
|
|
6
7
|
const config = useRuntimeConfig();
|
|
8
|
+
const route = useRoute();
|
|
7
9
|
const i18nConfig = config.public.i18nConfig;
|
|
10
|
+
const currentLocale = nuxtApp.$getLocale?.();
|
|
11
|
+
if (isMetaDisabledForRoute(route, i18nConfig.routeDisableMeta, currentLocale)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
8
14
|
const schema = port === "443" ? "https" : "http";
|
|
9
15
|
const defaultUrl = port === "80" || port === "443" ? `${schema}://${host}` : `${schema}://${host}:${port}`;
|
|
10
16
|
const url = useRequestURL();
|
|
11
17
|
const baseUrl = (i18nConfig.metaBaseUrl || url.origin || defaultUrl).toString();
|
|
12
|
-
const
|
|
18
|
+
const { metaObject, updateMeta } = useLocaleHead({
|
|
13
19
|
addDirAttribute: true,
|
|
14
20
|
identifierAttribute: "id",
|
|
15
21
|
addSeoAttributes: true,
|
|
16
22
|
baseUrl
|
|
17
23
|
});
|
|
18
|
-
useHead(
|
|
24
|
+
useHead(metaObject);
|
|
25
|
+
if (import.meta.server) {
|
|
26
|
+
updateMeta();
|
|
27
|
+
} else if (import.meta.client) {
|
|
28
|
+
watch(
|
|
29
|
+
() => useRoute().fullPath,
|
|
30
|
+
() => updateMeta(),
|
|
31
|
+
{ immediate: true }
|
|
32
|
+
);
|
|
33
|
+
}
|
|
19
34
|
});
|