nuxt-i18n-micro 1.6.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +3 -1
  2. package/dist/client/200.html +9 -9
  3. package/dist/client/404.html +9 -9
  4. package/dist/client/_nuxt/{DU08RbPQ.js → BjjmLJlJ.js} +1 -1
  5. package/dist/client/_nuxt/{CG2qJMgW.js → CODxK4mZ.js} +1 -1
  6. package/dist/client/_nuxt/Dsi6OVUM.js +1 -0
  7. package/dist/client/_nuxt/GiSJHq2i.js +119 -0
  8. package/dist/client/_nuxt/builds/latest.json +1 -1
  9. package/dist/client/_nuxt/builds/meta/d5645743-c1d7-431a-b761-c2ca1aa2b12b.json +1 -0
  10. package/dist/client/_nuxt/entry.BjfKHLcZ.css +1 -0
  11. package/dist/client/_nuxt/error-404.D-AvUzLt.css +1 -0
  12. package/dist/client/_nuxt/error-500.21ZDxC33.css +1 -0
  13. package/dist/client/index.html +9 -9
  14. package/dist/module.d.mts +5 -4
  15. package/dist/module.d.ts +5 -4
  16. package/dist/module.json +1 -1
  17. package/dist/module.mjs +30 -17
  18. package/dist/runtime/components/i18n-link.vue +12 -6
  19. package/dist/runtime/components/i18n-switcher.vue +85 -27
  20. package/dist/runtime/components/i18n-t.vue +93 -60
  21. package/dist/runtime/components/i18n-t.vue.d.ts +73 -0
  22. package/dist/runtime/composables/useLocaleHead.d.ts +22 -0
  23. package/dist/runtime/composables/useLocaleHead.js +97 -0
  24. package/dist/runtime/plugins/01.plugin.d.ts +2 -2
  25. package/dist/runtime/plugins/01.plugin.js +59 -107
  26. package/dist/runtime/plugins/02.meta.js +15 -45
  27. package/dist/runtime/translationHelper.d.ts +5 -5
  28. package/dist/runtime/translationHelper.js +24 -45
  29. package/package.json +20 -11
  30. package/dist/client/_nuxt/BOJGXfH_.js +0 -119
  31. package/dist/client/_nuxt/DyPhI3v_.js +0 -1
  32. package/dist/client/_nuxt/builds/meta/3583a2c9-2645-4710-9180-da6d201fe3ee.json +0 -1
  33. package/dist/client/_nuxt/entry.CF1WZhsD.css +0 -1
  34. package/dist/client/_nuxt/error-404.CjTTbIxB.css +0 -1
  35. package/dist/client/_nuxt/error-500.B4KzowuE.css +0 -1
@@ -0,0 +1,73 @@
1
+ declare const _default: import("vue").DefineComponent<{
2
+ keypath: {
3
+ type: StringConstructor;
4
+ required: true;
5
+ };
6
+ plural: {
7
+ type: (StringConstructor | NumberConstructor)[];
8
+ };
9
+ tag: {
10
+ type: StringConstructor;
11
+ default: string;
12
+ };
13
+ params: {
14
+ type: ObjectConstructor;
15
+ default: () => {};
16
+ };
17
+ defaultValue: {
18
+ type: StringConstructor;
19
+ default: string;
20
+ };
21
+ html: {
22
+ type: BooleanConstructor;
23
+ default: boolean;
24
+ };
25
+ hideIfEmpty: {
26
+ type: BooleanConstructor;
27
+ default: boolean;
28
+ };
29
+ customPluralRule: {
30
+ type: FunctionConstructor;
31
+ default: null;
32
+ };
33
+ }, () => any, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
34
+ keypath: {
35
+ type: StringConstructor;
36
+ required: true;
37
+ };
38
+ plural: {
39
+ type: (StringConstructor | NumberConstructor)[];
40
+ };
41
+ tag: {
42
+ type: StringConstructor;
43
+ default: string;
44
+ };
45
+ params: {
46
+ type: ObjectConstructor;
47
+ default: () => {};
48
+ };
49
+ defaultValue: {
50
+ type: StringConstructor;
51
+ default: string;
52
+ };
53
+ html: {
54
+ type: BooleanConstructor;
55
+ default: boolean;
56
+ };
57
+ hideIfEmpty: {
58
+ type: BooleanConstructor;
59
+ default: boolean;
60
+ };
61
+ customPluralRule: {
62
+ type: FunctionConstructor;
63
+ default: null;
64
+ };
65
+ }>>, {
66
+ tag: string;
67
+ params: Record<string, any>;
68
+ defaultValue: string;
69
+ html: boolean;
70
+ hideIfEmpty: boolean;
71
+ customPluralRule: Function;
72
+ }, {}>;
73
+ export default _default;
@@ -0,0 +1,22 @@
1
+ export declare const useLocaleHead: ({ addDirAttribute, identifierAttribute, addSeoAttributes, baseUrl }?: {
2
+ addDirAttribute?: boolean | undefined;
3
+ identifierAttribute?: string | undefined;
4
+ addSeoAttributes?: boolean | undefined;
5
+ baseUrl?: string | undefined;
6
+ }) => import("vue").Ref<{
7
+ htmlAttrs: {
8
+ lang?: string | undefined;
9
+ dir?: ("ltr" | "rtl" | "auto") | undefined;
10
+ };
11
+ link: {
12
+ [x: string]: string | undefined;
13
+ rel: string;
14
+ href: string;
15
+ hreflang?: string | undefined;
16
+ }[];
17
+ meta: {
18
+ [x: string]: string;
19
+ property: string;
20
+ content: string;
21
+ }[];
22
+ }>;
@@ -0,0 +1,97 @@
1
+ import { joinURL } from "ufo";
2
+ import { unref, useRoute, useRuntimeConfig, watch, onUnmounted, ref, useNuxtApp } from "#imports";
3
+ export const useLocaleHead = ({ addDirAttribute = true, identifierAttribute = "id", addSeoAttributes = true, baseUrl = "/" } = {}) => {
4
+ const metaObject = ref({
5
+ htmlAttrs: {},
6
+ link: [],
7
+ meta: []
8
+ });
9
+ function updateMeta() {
10
+ const { defaultLocale, includeDefaultLocaleRoute } = useRuntimeConfig().public.i18nConfig;
11
+ const { $getLocales, $getLocale } = useNuxtApp();
12
+ const route = useRoute();
13
+ const locale = unref($getLocale());
14
+ const routeName = (route.name ?? "").toString();
15
+ const currentLocale = unref($getLocales().find((l) => l.code === locale));
16
+ if (!currentLocale) {
17
+ return;
18
+ }
19
+ const currentIso = currentLocale.iso || locale;
20
+ const currentDir = currentLocale.dir || "auto";
21
+ let fullPath = unref(route.fullPath);
22
+ let ogUrl = joinURL(unref(baseUrl), fullPath);
23
+ let indexUrl = joinURL(unref(baseUrl));
24
+ if (!ogUrl.endsWith("/")) {
25
+ ogUrl += "/";
26
+ }
27
+ if (!indexUrl.endsWith("/")) {
28
+ indexUrl += "/";
29
+ }
30
+ if (routeName.startsWith("localized-") && fullPath.startsWith(`/${locale}`)) {
31
+ fullPath = fullPath.slice(locale.length + 1);
32
+ ogUrl = joinURL(unref(baseUrl), locale, fullPath);
33
+ }
34
+ metaObject.value = {
35
+ htmlAttrs: {
36
+ lang: currentIso,
37
+ ...addDirAttribute ? { dir: currentDir } : {}
38
+ },
39
+ link: [],
40
+ meta: []
41
+ };
42
+ if (!addSeoAttributes) return;
43
+ const alternateLocales = $getLocales() ?? [];
44
+ const ogLocaleMeta = {
45
+ [identifierAttribute]: "i18n-og",
46
+ property: "og:locale",
47
+ content: currentIso
48
+ };
49
+ const ogUrlMeta = {
50
+ [identifierAttribute]: "i18n-og-url",
51
+ property: "og:url",
52
+ content: ogUrl
53
+ };
54
+ const alternateOgLocalesMeta = alternateLocales.map((loc) => ({
55
+ [identifierAttribute]: `i18n-og-alt-${loc.iso || loc.code}`,
56
+ property: "og:locale:alternate",
57
+ content: unref(loc.iso || loc.code)
58
+ }));
59
+ const canonicalLink = {
60
+ [identifierAttribute]: "i18n-can",
61
+ rel: "canonical",
62
+ href: ogUrl
63
+ };
64
+ const alternateLinks = alternateLocales.flatMap((loc) => {
65
+ const href = defaultLocale === loc.code && !includeDefaultLocaleRoute ? indexUrl : joinURL(unref(baseUrl), loc.code, fullPath);
66
+ const links = [{
67
+ [identifierAttribute]: `i18n-alternate-${loc.code}`,
68
+ rel: "alternate",
69
+ href,
70
+ hreflang: unref(loc.code)
71
+ }];
72
+ if (loc.iso) {
73
+ links.push({
74
+ [identifierAttribute]: `i18n-alternate-${loc.iso}`,
75
+ rel: "alternate",
76
+ href,
77
+ hreflang: unref(loc.iso)
78
+ });
79
+ }
80
+ return links;
81
+ });
82
+ metaObject.value.meta = [ogLocaleMeta, ogUrlMeta, ...alternateOgLocalesMeta];
83
+ metaObject.value.link = [canonicalLink, ...alternateLinks];
84
+ }
85
+ if (import.meta.client) {
86
+ const route = useRoute();
87
+ const stop = watch(
88
+ () => route.fullPath,
89
+ () => updateMeta(),
90
+ { immediate: true }
91
+ );
92
+ onUnmounted(() => stop());
93
+ } else {
94
+ updateMeta();
95
+ }
96
+ return metaObject;
97
+ };
@@ -10,7 +10,7 @@ interface PluralTranslations {
10
10
  declare const _default: import("#app").Plugin<{
11
11
  getLocale: () => string;
12
12
  getLocales: () => Locale[];
13
- t: <T extends Record<string, string | number | boolean>>(key: string, params?: T, defaultValue?: string) => string | number | boolean | Translations | PluralTranslations | unknown[] | unknown | null;
13
+ t: (key: string, params?: Record<string, string | number | boolean>, defaultValue?: string) => unknown;
14
14
  tc: (key: string, count: number, defaultValue?: string) => string;
15
15
  has: (key: string) => boolean;
16
16
  mergeTranslations: (newTranslations: Translations) => void;
@@ -19,7 +19,7 @@ declare const _default: import("#app").Plugin<{
19
19
  }> & import("#app").ObjectPlugin<{
20
20
  getLocale: () => string;
21
21
  getLocales: () => Locale[];
22
- t: <T extends Record<string, string | number | boolean>>(key: string, params?: T, defaultValue?: string) => string | number | boolean | Translations | PluralTranslations | unknown[] | unknown | null;
22
+ t: (key: string, params?: Record<string, string | number | boolean>, defaultValue?: string) => unknown;
23
23
  tc: (key: string, count: number, defaultValue?: string) => string;
24
24
  has: (key: string) => boolean;
25
25
  mergeTranslations: (newTranslations: Translations) => void;
@@ -4,9 +4,13 @@ import { useRoute, useRouter } from "#imports";
4
4
  const i18nHelper = useTranslationHelper();
5
5
  const isDev = process.env.NODE_ENV !== "production";
6
6
  function interpolate(template, params) {
7
- return template.replace(/\{(\w+)\}/g, (_, match) => {
8
- return params[match] !== void 0 ? String(params[match]) : `{${match}}`;
9
- });
7
+ return template.replace(/\{(\w+)\}/g, (_, match) => params[match] !== void 0 ? String(params[match]) : `{${match}}`);
8
+ }
9
+ function getCurrentLocale(route, i18nConfig) {
10
+ return (route.params?.locale ?? i18nConfig.defaultLocale).toString();
11
+ }
12
+ function getRouteName(route) {
13
+ return (route?.name ?? "").toString().replace("localized-", "");
10
14
  }
11
15
  function switchLocale(locale, route, router, i18nConfig) {
12
16
  const checkLocale = i18nConfig.locales?.find((l) => l.code === locale);
@@ -14,157 +18,105 @@ function switchLocale(locale, route, router, i18nConfig) {
14
18
  console.warn(`Locale ${locale} is not available`);
15
19
  return Promise.reject(`Locale ${locale} is not available`);
16
20
  }
17
- const { defaultLocale } = i18nConfig;
18
- const routeName = route.name.replace(`localized-`, "");
19
- const newRouteName = locale !== defaultLocale || i18nConfig.includeDefaultLocaleRoute ? `localized-${routeName}` : routeName;
21
+ const routeName = getRouteName(route);
22
+ const newRouteName = locale !== i18nConfig.defaultLocale || i18nConfig.includeDefaultLocaleRoute ? `localized-${routeName}` : routeName;
20
23
  const newParams = { ...route.params };
21
24
  delete newParams.locale;
22
- if (locale !== defaultLocale || i18nConfig.includeDefaultLocaleRoute) {
25
+ if (locale !== i18nConfig.defaultLocale || i18nConfig.includeDefaultLocaleRoute) {
23
26
  newParams.locale = locale;
24
27
  }
25
28
  return router.push({ name: newRouteName, params: newParams });
26
29
  }
27
30
  function getLocalizedRoute(to, router, route, i18nConfig, locale) {
28
- const { defaultLocale } = i18nConfig;
29
- const currentLocale = (locale || route.params.locale || defaultLocale).toString();
31
+ const currentLocale = locale || getCurrentLocale(route, i18nConfig);
30
32
  const selectRoute = router.resolve(to);
31
- const routeName = selectRoute.name.replace(`localized-`, "");
32
- const newRouteName = currentLocale !== defaultLocale || i18nConfig.includeDefaultLocaleRoute ? `localized-${routeName}` : routeName;
33
+ const routeName = selectRoute.name.replace("localized-", "");
34
+ const newRouteName = currentLocale !== i18nConfig.defaultLocale || i18nConfig.includeDefaultLocaleRoute ? `localized-${routeName}` : routeName;
33
35
  const newParams = { ...route.params };
34
36
  delete newParams.locale;
35
- if (currentLocale !== defaultLocale || i18nConfig.includeDefaultLocaleRoute) {
37
+ if (currentLocale !== i18nConfig.defaultLocale || i18nConfig.includeDefaultLocaleRoute) {
36
38
  newParams.locale = currentLocale;
37
39
  }
38
40
  return router.resolve({ name: newRouteName, params: newParams });
39
41
  }
40
42
  export default defineNuxtPlugin(async (nuxtApp) => {
41
- const router = useRouter();
42
43
  const registerI18nModule = (translations, locale) => {
43
- i18nHelper.margeGlobalTranslation(locale, translations);
44
+ i18nHelper.mergeGlobalTranslation(locale, translations);
44
45
  };
45
46
  await nuxtApp.callHook("i18n:register", registerI18nModule);
46
47
  if (!nuxtApp.payload.data.translations) {
47
48
  nuxtApp.payload.data.translations = {};
48
49
  }
49
- if (import.meta.server) {
50
- nuxtApp.hook("app:rendered", async () => {
51
- if (import.meta.server) {
52
- const route2 = useRoute();
53
- const locale = (route2.params?.locale ?? i18nConfig.defaultLocale).toString();
54
- const routeName = (route2?.name ?? "").toString().replace(`localized-`, "");
55
- const cacheKey = `${locale}:${routeName}`;
56
- nuxtApp.payload.data.translations[cacheKey] = i18nHelper.getCache(locale, routeName) ?? /* @__PURE__ */ new Map();
57
- }
58
- });
59
- } else {
60
- router.beforeEach(async (to, from, next) => {
61
- const locale = (to.params?.locale ?? i18nConfig.defaultLocale).toString();
62
- const routeName = to.name.replace(`localized-`, "");
63
- const cacheKey = `${locale}:${routeName}`;
64
- if (nuxtApp.payload.data.translations) {
65
- i18nHelper.setCache(locale, routeName, nuxtApp.payload.data.translations[cacheKey] || /* @__PURE__ */ new Map());
66
- }
67
- next();
68
- });
69
- }
70
50
  const route = useRoute();
71
51
  const config = useRuntimeConfig();
72
52
  const i18nConfig = config.public.i18nConfig;
73
53
  const plural = new Function("return " + i18nConfig.plural)();
74
- router.beforeEach(async (to, from, next) => {
75
- if (import.meta.client) {
76
- const locale = (to.params?.locale ?? i18nConfig.defaultLocale).toString();
77
- const initialRouteName2 = to.name.replace(`localized-`, "");
78
- let routeName = initialRouteName2;
79
- if (i18nConfig.routesLocaleLinks && i18nConfig.routesLocaleLinks[routeName]) {
80
- routeName = i18nConfig.routesLocaleLinks[routeName];
81
- }
82
- if (!i18nHelper.hasPageTranslation(locale, initialRouteName2)) {
83
- const data = await $fetch(`/_locales/${routeName}/${locale}/data.json?v=${i18nConfig.dateBuild}`, { baseURL: i18nConfig.baseURL });
84
- await i18nHelper.loadPageTranslations(locale, initialRouteName2, data ?? {});
85
- }
86
- }
87
- next();
88
- });
89
- const initialLocale = (route.params?.locale ?? i18nConfig.defaultLocale).toString();
90
- const initialRouteName = route.name.replace(`localized-`, "");
54
+ const initialLocale = getCurrentLocale(route, i18nConfig);
91
55
  if (!i18nHelper.hasGeneralTranslation(initialLocale)) {
92
56
  const data = await $fetch(`/_locales/general/${initialLocale}/data.json?v=${i18nConfig.dateBuild}`, { baseURL: i18nConfig.baseURL });
93
57
  await i18nHelper.loadTranslations(initialLocale, data ?? {});
94
58
  }
59
+ const loadTranslationsIfNeeded = async (locale, routeName) => {
60
+ if (!i18nHelper.hasPageTranslation(locale, routeName)) {
61
+ let fRouteName = routeName;
62
+ if (i18nConfig.routesLocaleLinks && i18nConfig.routesLocaleLinks[fRouteName]) {
63
+ fRouteName = i18nConfig.routesLocaleLinks[fRouteName];
64
+ }
65
+ const data = await $fetch(`/_locales/${fRouteName}/${locale}/data.json?v=${i18nConfig.dateBuild}`, { baseURL: i18nConfig.baseURL });
66
+ await i18nHelper.loadPageTranslations(locale, routeName, data ?? {});
67
+ }
68
+ };
95
69
  if (import.meta.server) {
96
- const locale = (route.params?.locale ?? i18nConfig.defaultLocale).toString();
97
- let routeName = initialRouteName;
98
- if (i18nConfig.routesLocaleLinks && i18nConfig.routesLocaleLinks[routeName]) {
99
- routeName = i18nConfig.routesLocaleLinks[routeName];
70
+ const locale = getCurrentLocale(route, i18nConfig);
71
+ const initialRouteName = getRouteName(route);
72
+ await loadTranslationsIfNeeded(locale, initialRouteName);
73
+ }
74
+ useRouter().beforeEach(async (to, from, next) => {
75
+ if (import.meta.client) {
76
+ const locale = getCurrentLocale(to, i18nConfig);
77
+ const routeName = getRouteName(to);
78
+ await loadTranslationsIfNeeded(locale, routeName);
100
79
  }
101
- if (!i18nHelper.hasPageTranslation(initialLocale, routeName)) {
102
- const pageData = await $fetch(`/_locales/${routeName}/${locale}/data.json?v=${i18nConfig.dateBuild}`, { baseURL: i18nConfig.baseURL });
103
- await i18nHelper.loadPageTranslations(initialLocale, initialRouteName, pageData ?? {});
80
+ next();
81
+ });
82
+ const getTranslation = (key, params, defaultValue) => {
83
+ if (!key) return "";
84
+ const locale = getCurrentLocale(useRoute(), i18nConfig);
85
+ const routeName = getRouteName(useRoute());
86
+ let value = i18nHelper.getTranslation(locale, routeName, key);
87
+ if (!value) {
88
+ if (isDev && import.meta.client) {
89
+ console.warn(`Not found '${key}' key in '${locale}' locale messages.`);
90
+ }
91
+ value = defaultValue || key;
104
92
  }
105
- }
93
+ return typeof value === "string" && params ? interpolate(value, params) : value;
94
+ };
106
95
  return {
107
96
  provide: {
108
- getLocale: () => {
109
- const route2 = useRoute();
110
- return (route2.params?.locale ?? i18nConfig.defaultLocale).toString();
111
- },
97
+ getLocale: () => getCurrentLocale(useRoute(), i18nConfig),
112
98
  getLocales: () => i18nConfig.locales || [],
113
- t: (key, params, defaultValue) => {
114
- if (!key) {
115
- console.log(`$t: key not exist`);
116
- return "";
117
- }
118
- const route2 = useRoute();
119
- const locale = (route2.params?.locale ?? i18nConfig.defaultLocale).toString();
120
- const routeName = route2.name.replace(`localized-`, "");
121
- let value = i18nHelper.getTranslation(locale, routeName, key, !!i18nConfig.cache);
122
- if (!value) {
123
- if (isDev && import.meta.client) {
124
- console.warn(`Not found '${key}' key in '${locale}' locale messages.`);
125
- }
126
- value = defaultValue || key;
127
- }
128
- if (typeof value === "string" && params) {
129
- value = interpolate(value, params);
130
- }
131
- return value;
132
- },
99
+ t: getTranslation,
133
100
  tc: (key, count, defaultValue) => {
134
- if (!key) {
135
- console.log(`$tc: key not exist`);
136
- return "";
137
- }
138
- const route2 = useRoute();
139
- const locale = (route2.params?.locale ?? i18nConfig.defaultLocale).toString();
140
- const routeName = route2.name.replace(`localized-`, "");
141
- let translation = i18nHelper.getTranslation(locale, routeName, key, !!i18nConfig.cache);
142
- if (!translation) {
143
- if (isDev && import.meta.client) {
144
- console.warn(`Not found '${key}' key in '${locale}' locale messages.`);
145
- }
146
- translation = defaultValue || key;
147
- }
148
- return plural(translation.toString(), count, locale);
101
+ const translation = getTranslation(key, {}, defaultValue);
102
+ return plural(translation?.toString(), count, getCurrentLocale(useRoute(), i18nConfig));
149
103
  },
150
104
  has: (key) => {
151
- const route2 = useRoute();
152
- const locale = (route2.params?.locale ?? i18nConfig.defaultLocale).toString();
153
- const routeName = route2.name.replace(`localized-`, "");
154
- const translation = i18nHelper.getTranslation(locale, routeName, key, !!i18nConfig.cache);
155
- return !!translation;
105
+ return !!getTranslation(key);
156
106
  },
157
107
  mergeTranslations: (newTranslations) => {
158
108
  const route2 = useRoute();
159
- const routeName = route2.name.replace(`localized-`, "");
160
- const locale = (route2.params?.locale ?? i18nConfig.defaultLocale).toString();
161
- i18nHelper.margeTranslation(locale, routeName, newTranslations);
109
+ const routeName = getRouteName(route2);
110
+ const locale = getCurrentLocale(route2, i18nConfig);
111
+ i18nHelper.mergeTranslation(locale, routeName, newTranslations);
162
112
  },
163
113
  switchLocale: (locale) => {
114
+ const router = useRouter();
164
115
  const route2 = useRoute();
165
116
  switchLocale(locale, route2, router, i18nConfig);
166
117
  },
167
118
  localeRoute: (to, locale) => {
119
+ const router = useRouter();
168
120
  const route2 = useRoute();
169
121
  return getLocalizedRoute(to, router, route2, i18nConfig, locale);
170
122
  }
@@ -1,55 +1,25 @@
1
+ import { useLocaleHead } from "../composables/useLocaleHead.js";
1
2
  import { useHead, defineNuxtPlugin, useRuntimeConfig } from "#app";
2
- import { useRoute } from "#imports";
3
+ import { useRequestURL } from "#imports";
4
+ const host = process.env.HOST ?? "localhost";
5
+ const port = process.env.PORT ?? "host";
3
6
  export default defineNuxtPlugin((nuxtApp) => {
4
- const route = useRoute();
5
7
  const config = useRuntimeConfig();
6
8
  const i18nConfig = config.public.i18nConfig;
7
- if (!i18nConfig.mata) {
9
+ const schema = port === "443" ? "https" : "http";
10
+ const defaultUrl = port === "80" || port === "443" ? `${schema}://${host}` : `${schema}://${host}:${port}`;
11
+ if (!i18nConfig.meta) {
8
12
  return;
9
13
  }
10
14
  nuxtApp.hook("app:rendered", (_context) => {
11
- const locale = (route.params?.locale ?? i18nConfig.defaultLocale).toString();
12
- const locales = i18nConfig.locales || [];
13
- const currentIso = locales.find((l) => l.code === locale)?.iso || locale;
14
- const currentDir = locales.find((l) => l.code === locale)?.dir || "ltr";
15
- const baseUrl = config.public.baseURL || "http://localhost:3000";
16
- const ogUrl = `${baseUrl}${route.fullPath}`;
17
- useHead({
18
- htmlAttrs: {
19
- lang: currentIso,
20
- dir: currentDir
21
- },
22
- meta: [
23
- { id: "i18n-og", property: "og:locale", content: currentIso },
24
- { id: "i18n-og-url", property: "og:url", content: ogUrl },
25
- ...locales.filter((l) => l.code !== locale).map((loc) => ({
26
- id: `i18n-og-alt-${loc.iso || loc.code}`,
27
- property: "og:locale:alternate",
28
- content: loc.iso || loc.code
29
- }))
30
- ],
31
- link: [
32
- { id: "i18n-can", rel: "canonical", href: ogUrl },
33
- ...locales.flatMap((loc) => {
34
- const links = [
35
- {
36
- id: `i18n-alternate-${loc.code}`,
37
- rel: "alternate",
38
- href: `${baseUrl}/${loc.code}${route.fullPath}`,
39
- hreflang: loc.code
40
- }
41
- ];
42
- if (loc.iso) {
43
- links.push({
44
- id: `i18n-alternate-${loc.iso}`,
45
- rel: "alternate",
46
- href: `${baseUrl}/${loc.code}${route.fullPath}`,
47
- hreflang: loc.iso
48
- });
49
- }
50
- return links;
51
- })
52
- ]
15
+ const url = useRequestURL();
16
+ const baseUrl = (i18nConfig.metaBaseUrl || url.origin || defaultUrl).toString();
17
+ const head = useLocaleHead({
18
+ addDirAttribute: true,
19
+ identifierAttribute: "id",
20
+ addSeoAttributes: true,
21
+ baseUrl
53
22
  });
23
+ useHead(head);
54
24
  });
55
25
  });
@@ -3,11 +3,11 @@ export declare function useTranslationHelper(): {
3
3
  hasCache(locale: string, page: string): boolean;
4
4
  getCache(locale: string, routeName: string): Map<string, unknown>;
5
5
  setCache(locale: string, routeName: string, cache: Map<string, Translations | unknown>): void;
6
- margeTranslation(locale: string, routeName: string, newTranslations: Translations): void;
7
- margeGlobalTranslation(locale: string, newTranslations: Translations): void;
6
+ mergeTranslation(locale: string, routeName: string, newTranslations: Translations): void;
7
+ mergeGlobalTranslation(locale: string, newTranslations: Translations): void;
8
8
  hasGeneralTranslation(locale: string): boolean;
9
9
  hasPageTranslation(locale: string, routeName: string): boolean;
10
- getTranslation: <T = unknown>(locale: string, routeName: string, key: string, useCache: boolean) => T | null;
11
- loadPageTranslations: (locale: string, routeName: string, translations: Translations) => Promise<void>;
12
- loadTranslations: (locale: string, translations: Translations) => Promise<void>;
10
+ getTranslation: <T = unknown>(locale: string, routeName: string, key: string) => T | null;
11
+ loadPageTranslations(locale: string, routeName: string, translations: Translations): Promise<void>;
12
+ loadTranslations(locale: string, translations: Translations): Promise<void>;
13
13
  };
@@ -13,9 +13,9 @@ function deepClone(value) {
13
13
  }
14
14
  function findTranslation(translations, parts) {
15
15
  let value = translations;
16
- for (let i = 0; i < parts.length; i++) {
17
- if (value && typeof value === "object" && parts[i] in value) {
18
- value = value[parts[i]];
16
+ for (const part of parts) {
17
+ if (value && typeof value === "object" && part in value) {
18
+ value = value[part];
19
19
  } else {
20
20
  return null;
21
21
  }
@@ -28,17 +28,18 @@ function findTranslation(translations, parts) {
28
28
  export function useTranslationHelper() {
29
29
  return {
30
30
  hasCache(locale, page) {
31
- return serverTranslationInit[`${locale}:${page}`] ?? false;
31
+ return (serverTranslationCache[`${locale}:${page}`] ?? /* @__PURE__ */ new Map()).size > 0;
32
32
  },
33
33
  getCache(locale, routeName) {
34
34
  return serverTranslationCache[`${locale}:${routeName}`];
35
35
  },
36
36
  setCache(locale, routeName, cache) {
37
+ const cacheKey = `${locale}:${routeName}`;
37
38
  serverTranslationCache[`${locale}:${routeName}`] = cache;
38
39
  serverTranslationInit[`${locale}:index`] = true;
39
- serverTranslationInit[`${locale}:${routeName}`] = true;
40
+ serverTranslationInit[cacheKey] = true;
40
41
  },
41
- margeTranslation(locale, routeName, newTranslations) {
42
+ mergeTranslation(locale, routeName, newTranslations) {
42
43
  if (!routeLocaleCache[`${locale}:${routeName}`]) {
43
44
  console.error(`marge: route ${locale}:${routeName} not loaded`);
44
45
  }
@@ -47,7 +48,7 @@ export function useTranslationHelper() {
47
48
  ...newTranslations
48
49
  };
49
50
  },
50
- margeGlobalTranslation(locale, newTranslations) {
51
+ mergeGlobalTranslation(locale, newTranslations) {
51
52
  if (!generalLocaleCache[`${locale}`]) {
52
53
  console.error(`marge: route ${locale} not loaded`);
53
54
  }
@@ -62,37 +63,22 @@ export function useTranslationHelper() {
62
63
  hasPageTranslation(locale, routeName) {
63
64
  return !!routeLocaleCache[`${locale}:${routeName}`];
64
65
  },
65
- getTranslation: (locale, routeName, key, useCache) => {
66
+ getTranslation: (locale, routeName, key) => {
66
67
  const cacheKey = `${locale}:${routeName}`;
67
- if (useCache && serverTranslationCache[cacheKey]) {
68
- const cached = serverTranslationCache[cacheKey].get(key);
69
- if (cached) {
70
- return cached;
71
- }
68
+ const cached = serverTranslationCache[cacheKey]?.get(key);
69
+ if (cached) {
70
+ return cached;
72
71
  }
73
72
  const parts = key.split(".");
74
73
  let result = null;
75
- if (dynamicTranslationsCaches.length) {
76
- for (const dynamicCache of dynamicTranslationsCaches) {
77
- const value = findTranslation(dynamicCache[locale], parts);
78
- if (value !== null) {
79
- result = value;
80
- }
81
- }
74
+ for (const dynamicCache of dynamicTranslationsCaches) {
75
+ result = findTranslation(dynamicCache[locale] || null, parts);
76
+ if (result !== null) break;
82
77
  }
83
78
  if (!result) {
84
- const value = findTranslation(routeLocaleCache[`${locale}:${routeName}`], parts);
85
- if (value !== null) {
86
- result = value;
87
- }
79
+ result = findTranslation(routeLocaleCache[cacheKey] || null, parts) ?? findTranslation(generalLocaleCache[locale] || null, parts);
88
80
  }
89
- if (!result) {
90
- const value = findTranslation(generalLocaleCache[locale], parts);
91
- if (value !== null) {
92
- return value;
93
- }
94
- }
95
- if (useCache && result) {
81
+ if (result) {
96
82
  if (!serverTranslationCache[cacheKey]) {
97
83
  serverTranslationCache[cacheKey] = /* @__PURE__ */ new Map();
98
84
  }
@@ -100,21 +86,14 @@ export function useTranslationHelper() {
100
86
  }
101
87
  return result;
102
88
  },
103
- loadPageTranslations: async (locale, routeName, translations) => {
104
- try {
105
- routeLocaleCache[`${locale}:${routeName}`] = { ...translations };
106
- serverTranslationInit[`${locale}:${routeName}`] = true;
107
- } catch (error) {
108
- console.error(`Error loading translations for ${locale} and ${routeName}:`, error);
109
- }
89
+ async loadPageTranslations(locale, routeName, translations) {
90
+ const cacheKey = `${locale}:${routeName}`;
91
+ routeLocaleCache[cacheKey] = { ...translations };
92
+ serverTranslationInit[cacheKey] = true;
110
93
  },
111
- loadTranslations: async (locale, translations) => {
112
- try {
113
- generalLocaleCache[locale] = { ...translations };
114
- serverTranslationInit[`${locale}:index`] = true;
115
- } catch (error) {
116
- console.error(`Error loading translations for general ${locale}:`, error);
117
- }
94
+ async loadTranslations(locale, translations) {
95
+ generalLocaleCache[locale] = { ...translations };
96
+ serverTranslationInit[`${locale}:index`] = true;
118
97
  }
119
98
  };
120
99
  }