@nuxtjs/i18n
Version:
Internationalization for Nuxt
127 lines (126 loc) • 4.69 kB
JavaScript
import { hasProtocol, joinURL, parsePath, parseQuery, withTrailingSlash, withoutTrailingSlash } from "ufo";
import { DEFAULT_DYNAMIC_PARAMS_KEY } from "#build/i18n.options.mjs";
import { assign, isObject, isString } from "@intlify/shared";
import { isNavigationFailure } from "vue-router";
import { unref } from "#imports";
import { getI18nTarget } from "../compatibility.js";
import { getDomainFromLocale } from "../domain.js";
import { getLocaleRouteName, getRouteName } from "./utils.js";
import { prefixable } from "../utils.js";
export function getRouteBaseName(common, route) {
const _route = unref(route);
const routeName = isObject(_route) ? _route?.name : _route;
if (_route == null || !routeName) {
return;
}
return getRouteName(routeName).split(common.runtimeConfig.public.i18n.routesNameSeparator)[0];
}
export function localePath(common, route, locale) {
if (isString(route) && hasProtocol(route, { acceptRelative: true })) {
return route;
}
const localizedRoute = resolveRoute(common, route, locale);
return localizedRoute == null ? "" : localizedRoute.redirectedFrom?.fullPath || localizedRoute.fullPath;
}
export function localeRoute(common, route, locale) {
return resolveRoute(common, route, locale) ?? void 0;
}
function normalizeRawLocation(route) {
if (!isString(route)) {
return assign({}, route);
}
if (route[0] === "/") {
const { pathname: path, search, hash } = parsePath(route);
return { path, query: parseQuery(search), hash };
}
return { name: route };
}
const isRouteLocationPathRaw = (val) => !!val.path && !val.name;
function resolveRouteObject(common, route, locale) {
const runtimeI18n = common.runtimeConfig.public.i18n;
if (isRouteLocationPathRaw(route)) {
const resolved = resolve(common, route, locale);
const resolvedName = getRouteBaseName(common, resolved);
if (resolvedName) {
resolved.name = getLocaleRouteName(resolvedName, locale, runtimeI18n);
return resolved;
}
if (!runtimeI18n.differentDomains && prefixable(locale, runtimeI18n.defaultLocale, runtimeI18n.strategy)) {
route.path = "/" + locale + route.path;
}
route.path = (runtimeI18n.trailingSlash ? withTrailingSlash : withoutTrailingSlash)(route.path, true);
return route;
}
route.name ||= getRouteBaseName(common, common.router.currentRoute.value);
const localizedName = getLocaleRouteName(route.name, locale, runtimeI18n);
if (common.router.hasRoute(localizedName)) {
route.name = localizedName;
}
return route;
}
export function resolveRoute(common, route, locale) {
try {
const _locale = locale || unref(getI18nTarget(common.i18n).locale);
const normalized = normalizeRawLocation(route);
const resolved = common.router.resolve(resolveRouteObject(common, normalized, _locale));
if (resolved.name) {
return resolved;
}
return common.router.resolve(route);
} catch (e) {
if (isNavigationFailure(
e,
1
/* No match */
)) {
return null;
}
}
}
function getLocalizableMetaFromDynamicParams(common, route) {
if (common.runtimeConfig.public.i18n.experimental.switchLocalePathLinkSSR) {
return unref(common.metaState.value);
}
const meta = route.meta || {};
return unref(meta)?.[DEFAULT_DYNAMIC_PARAMS_KEY] || {};
}
export function switchLocalePath(common, locale, _route) {
const route = _route ?? common.router.currentRoute.value;
const name = getRouteBaseName(common, route);
if (!name) {
return "";
}
const resolvedParams = getLocalizableMetaFromDynamicParams(common, route)[locale];
const routeCopy = {
name,
params: assign({}, route.params, resolvedParams),
fullPath: route.fullPath,
query: route.query,
hash: route.hash,
path: route.path,
meta: route.meta
// matched: route.matched,
// redirectedFrom: route.redirectedFrom
};
const path = localePath(common, routeCopy, locale);
if (common.runtimeConfig.public.i18n.differentDomains) {
const domain = getDomainFromLocale(locale);
return domain && joinURL(domain, path) || path;
}
return path;
}
function resolve(common, route, locale) {
if (common.runtimeConfig.public.i18n.strategy === "no_prefix") {
return route;
}
if (common.runtimeConfig.public.i18n.strategy !== "prefix") {
return common.router.resolve(route);
}
const restPath = route.path.slice(1);
const targetPath = route.path[0] + locale + (restPath && "/" + restPath);
const _route = common.router.options.routes.find((r) => r.path === targetPath);
if (_route == null) {
return route;
}
return common.router.resolve(assign({}, route, _route, { path: targetPath }));
}