UNPKG

@nuxtjs/i18n

Version:

Internationalization for Nuxt

127 lines (126 loc) 4.69 kB
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 })); }