nuxt-i18n-micro
Version:
Nuxt I18n Micro is a lightweight, high-performance internationalization module for Nuxt, designed to handle multi-language support with minimal overhead, fast build times, and efficient runtime performance.
89 lines (88 loc) • 3.52 kB
JavaScript
import { isPrefixStrategy, isNoPrefixStrategy } from "nuxt-i18n-micro-core";
import { defineNuxtPlugin, useCookie, useRequestHeaders, navigateTo, useRoute, useRouter } from "#imports";
const parseAcceptLanguage = (acceptLanguage) => acceptLanguage.split(",").map((entry) => {
const parts = entry.split(";");
return parts[0] ? parts[0].trim() : "";
});
export default defineNuxtPlugin(async (nuxtApp) => {
const i18nConfig = nuxtApp.$config.public.i18nConfig;
const date = /* @__PURE__ */ new Date();
const userLocaleCookie = useCookie(i18nConfig.localeCookie || "user-locale", {
watch: false,
expires: new Date(date.setDate(date.getDate() + 365))
});
const hashCookie = useCookie("hash-locale");
const headers = useRequestHeaders(["accept-language"]);
const supportedLocales = i18nConfig.locales?.map((locale) => locale.code) ?? [];
const defaultLocale = i18nConfig.defaultLocale || "en";
const autoDetectPath = i18nConfig.autoDetectPath || "/";
const router = useRouter();
const route = useRoute();
async function switchLocale(newLocale) {
if (isNoPrefixStrategy(i18nConfig.strategy)) {
if (newLocale !== defaultLocale) {
const newParams2 = { ...route.params };
delete newParams2.locale;
const resolvedRoute2 = router.resolve(router.currentRoute.value);
const routeName2 = resolvedRoute2.name.replace(`localized-`, "");
const newRoute2 = router.resolve({
name: routeName2,
params: newParams2
});
const userLocaleCookie2 = useCookie("no-prefix-locale");
userLocaleCookie2.value = newLocale;
await navigateTo(newRoute2, {
redirectCode: 302,
external: true
});
}
return;
}
const currentPath = router.currentRoute;
const resolvedRoute = router.resolve(currentPath.value);
const routeName = resolvedRoute.name.replace(`localized-`, "");
const newRouteName = isPrefixStrategy(i18nConfig.strategy) || newLocale !== defaultLocale ? `localized-${routeName}` : routeName;
const newParams = { ...route.params };
delete newParams.locale;
if (!isNoPrefixStrategy(i18nConfig.strategy)) {
if (isPrefixStrategy(i18nConfig.strategy) || newLocale !== defaultLocale) {
newParams.locale = newLocale;
}
}
const newRoute = router.resolve({
name: newRouteName,
params: newParams
});
await navigateTo(newRoute.href, {
redirectCode: 302,
external: true
});
}
if (userLocaleCookie.value || i18nConfig.isSSG) {
return;
}
if (autoDetectPath !== "*" && route.path !== autoDetectPath) {
return;
}
const acceptLanguage = headers?.["accept-language"] ?? "";
const browserLanguages = acceptLanguage ? parseAcceptLanguage(acceptLanguage) : [defaultLocale];
let detectedLocale = defaultLocale;
for (const language of browserLanguages) {
const lowerCaseLanguage = language.toLowerCase();
const primaryLanguage = lowerCaseLanguage.split("-")[0];
detectedLocale = supportedLocales.find(
(locale) => locale.toLowerCase() === lowerCaseLanguage || locale.toLowerCase() === primaryLanguage
);
if (detectedLocale) break;
}
if (detectedLocale) {
userLocaleCookie.value = detectedLocale;
if (i18nConfig.hashMode) {
hashCookie.value = detectedLocale;
}
const currentLocale = route.params.locale ?? defaultLocale;
if (detectedLocale !== currentLocale) {
await switchLocale(detectedLocale);
}
}
});