diff --git a/src/module.ts b/src/module.ts index 9041fdcea..981430f4c 100644 --- a/src/module.ts +++ b/src/module.ts @@ -213,10 +213,8 @@ export default defineNuxtModule({ nuxtI18nOptions, isServer }), - NUXT_I18N_MODULE_ID, localeCodes, - nuxtI18nOptionsDefault: DEFAULT_OPTIONS, - nuxtI18nInternalOptions: { __normalizedLocales: normalizedLocales as SimpleLocaleObject[] }, + normalizedLocales, dev: nuxt.options.dev, isSSG: nuxt.options._generate, parallelPlugin: options.parallelPlugin diff --git a/src/options.d.ts b/src/options.d.ts index b0fd31ea6..36b347722 100644 --- a/src/options.d.ts +++ b/src/options.d.ts @@ -1,5 +1,5 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import type { NuxtI18nOptions, NuxtI18nInternalOptions, VueI18nConfig } from './types' +import type { NuxtI18nOptions, VueI18nConfig } from './types' import type { NuxtI18nOptionsDefault } from './constants' import type { DeepRequired } from 'ts-essentials' @@ -25,7 +25,7 @@ export const vueI18nConfigs: VueI18nConfig[] export const localeCodes: string[] = [] export const nuxtI18nOptions: DeepRequired> = {} export const nuxtI18nOptionsDefault: NuxtI18nOptionsDefault = {} -export const nuxtI18nInternalOptions: DeepRequired = {} +export const normalizedLocales: LocaleObject[] = [] export const NUXT_I18N_MODULE_ID = '' export const isSSG = false export const parallelPlugin: boolean @@ -43,7 +43,6 @@ export const DEFAULT_DYNAMIC_PARAMS_KEY: typeof constants.DEFAULT_DYNAMIC_PARAMS export { NuxtI18nOptions, NuxtI18nOptionsDefault, - NuxtI18nInternalOptions, DetectBrowserLanguageOptions, RootRedirectOptions } from './types' diff --git a/src/runtime/composables/index.ts b/src/runtime/composables/index.ts index 49907a818..efe457b74 100644 --- a/src/runtime/composables/index.ts +++ b/src/runtime/composables/index.ts @@ -1,17 +1,11 @@ -import { useRoute, useRequestHeaders, useCookie, useRouter } from '#imports' +import { useRoute, useRouter, useRequestHeaders, useCookie as useNuxtCookie, useNuxtApp } from '#imports' import { ref, computed, watch, onUnmounted } from 'vue' import { parseAcceptLanguage } from '../internal' -import { nuxtI18nInternalOptions, nuxtI18nOptionsDefault, localeCodes as _localeCodes } from '#build/i18n.options.mjs' +import { localeCodes, normalizedLocales, nuxtI18nOptions, type I18nHeadMetaInfo, type I18nHeadOptions, type SeoAttributesOptions } from '#build/i18n.options.mjs' import { getActiveHead } from 'unhead' import { useI18n } from 'vue-i18n' import type { Ref } from 'vue' -import type { - DetectBrowserLanguageOptions, - I18nHeadMetaInfo, - I18nHeadOptions, - SeoAttributesOptions -} from '#build/i18n.options.mjs' export * from 'vue-i18n' export * from './shared' @@ -328,7 +322,7 @@ export function useSwitchLocalePath(): SwitchLocalePathFunction { * * @public */ -export function useBrowserLocale(normalizedLocales = nuxtI18nInternalOptions.__normalizedLocales): string | null { +export function useBrowserLocale(): string | null { const headers = useRequestHeaders(['accept-language']) return ( findBrowserLocale( @@ -350,30 +344,24 @@ export function useBrowserLocale(normalizedLocales = nuxtI18nInternalOptions.__n * * @public */ -export function useCookieLocale( - options: Required> & { - localeCodes: readonly string[] - } = { - useCookie: nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie, - cookieKey: nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey, - localeCodes: _localeCodes - } -): Ref { +export function useCookieLocale(): Ref { // Support for importing from `#imports` is generated by auto `imports` nuxt module, so `ref` is imported from `vue` const locale: Ref = ref('') + const detect = nuxtI18nOptions.detectBrowserLanguage + + if (detect && detect.useCookie) { + const cookieKey = detect.cookieKey - if (options.useCookie) { let code: string | null = null if (process.client) { - const cookie = useCookie(options.cookieKey) as Ref - code = cookie.value + code = useNuxtCookie(cookieKey).value } else if (process.server) { const cookie = useRequestHeaders(['cookie']) // eslint-disable-next-line @typescript-eslint/no-explicit-any - code = (cookie as any)[options.cookieKey] + code = (cookie as any)[cookieKey] } - if (code && options.localeCodes.includes(code)) { + if (code && localeCodes.includes(code)) { locale.value = code } } diff --git a/src/runtime/internal.ts b/src/runtime/internal.ts index 07dcbf4b0..730a64a7a 100644 --- a/src/runtime/internal.ts +++ b/src/runtime/internal.ts @@ -11,17 +11,18 @@ import { useNuxtApp, unref } from '#imports' -import { nuxtI18nOptionsDefault, NUXT_I18N_MODULE_ID, isSSG } from '#build/i18n.options.mjs' +import { + nuxtI18nOptionsDefault, + NUXT_I18N_MODULE_ID, + isSSG, + localeCodes, + nuxtI18nOptions, + normalizedLocales +} from '#build/i18n.options.mjs' import type { NuxtApp } from '#app' -import type { I18nOptions, Locale } from 'vue-i18n' -import type { DeepRequired } from 'ts-essentials' -import type { - NuxtI18nOptions, - NuxtI18nInternalOptions, - DetectBrowserLanguageOptions, - LocaleObject -} from '#build/i18n.options.mjs' +import type { Locale } from 'vue-i18n' +import type { DetectBrowserLanguageOptions, LocaleObject } from '#build/i18n.options.mjs' import { findBrowserLocale, getLocalesRegex, getI18nTarget } from './routing/utils' import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router' @@ -81,14 +82,13 @@ export function parseAcceptLanguage(input: string): string[] { return input.split(',').map(tag => tag.split(';')[0]) } -// eslint-disable-next-line @typescript-eslint/no-unused-vars -export function getBrowserLocale(options: Required): string | undefined { +export function getBrowserLocale(): string | undefined { let ret: string | undefined if (process.client) { if (navigator.languages) { // get browser language either from navigator if running on client side, or from the headers - ret = findBrowserLocale(options.__normalizedLocales, navigator.languages as string[]) + ret = findBrowserLocale(normalizedLocales, navigator.languages as string[]) __DEBUG__ && console.log('getBrowserLocale (navigator.languages, ret) -', navigator.languages, ret) } } else if (process.server) { @@ -96,7 +96,7 @@ export function getBrowserLocale(options: Required): st __DEBUG__ && console.log('getBrowserLocale accept-language', header) const accept = header['accept-language'] if (accept) { - ret = findBrowserLocale(options.__normalizedLocales, parseAcceptLanguage(accept)) + ret = findBrowserLocale(normalizedLocales, parseAcceptLanguage(accept)) __DEBUG__ && console.log('getBrowserLocale ret', ret) } } @@ -104,19 +104,21 @@ export function getBrowserLocale(options: Required): st return ret } -export function getLocaleCookie({ - useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie, - cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey, - localeCodes = [] -}: Pick & { - localeCodes?: readonly string[] -} = {}): string | undefined { - __DEBUG__ && console.log('getLocaleCookie', { useCookie, cookieKey, localeCodes }) - if (!useCookie) { +export function getLocaleCookie(): string | undefined { + const detect = nuxtI18nOptions.detectBrowserLanguage + + __DEBUG__ && + console.log('getLocaleCookie', { + useCookie: detect && detect.useCookie, + cookieKey: detect && detect.cookieKey, + localeCodes + }) + + if (!detect || !detect.useCookie) { return } - const localeCookie = useNuxtCookie(cookieKey) + const localeCookie = useNuxtCookie(detect.cookieKey) const localeCode: string | undefined = localeCookie.value ?? undefined __DEBUG__ && console.log(`getLocaleCookie cookie (${process.client ? 'client' : 'server'}) -`, localeCode) @@ -125,19 +127,10 @@ export function getLocaleCookie({ } } -export function setLocaleCookie( - locale: string, - { - useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie, - cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey, - cookieDomain = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieDomain, - cookieSecure = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieSecure, - cookieCrossOrigin = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieCrossOrigin - }: Pick< - DetectBrowserLanguageOptions, - 'useCookie' | 'cookieDomain' | 'cookieKey' | 'cookieSecure' | 'cookieCrossOrigin' - > = {} -) { +export function setLocaleCookie(locale: string) { + const { useCookie, cookieKey, cookieDomain, cookieSecure, cookieCrossOrigin } = + nuxtI18nOptions.detectBrowserLanguage || nuxtI18nOptionsDefault.detectBrowserLanguage + if (!useCookie) { return } @@ -187,13 +180,10 @@ export const DefaultDetectBrowserLanguageFromResult: DetectBrowserLanguageFromRe from: 'unknown' } -export function detectBrowserLanguage( +export function detectBrowserLanguage( route: string | RouteLocationNormalized | RouteLocationNormalizedLoaded, - nuxtI18nOptions: DeepRequired>, - nuxtI18nInternalOptions: DeepRequired, - vueI18nOptions: I18nOptions, + vueI18nOptionsLocale: Locale | undefined, detectLocaleContext: DetectLocaleContext, - localeCodes: string[] = [], locale: Locale = '' ): DetectBrowserLanguageFromResult { const { strategy } = nuxtI18nOptions @@ -244,13 +234,13 @@ export function detectBrowserLanguage( // get preferred language from cookie if present and enabled if (useCookie) { - matchedLocale = cookieLocale = getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes }) + matchedLocale = cookieLocale = getLocaleCookie() localeFrom = 'cookie' __DEBUG__ && console.log('detectBrowserLanguage: cookieLocale', cookieLocale) } // try to get locale from either navigator or header detection if (!matchedLocale) { - matchedLocale = getBrowserLocale(nuxtI18nInternalOptions) + matchedLocale = getBrowserLocale() localeFrom = 'navigator_or_header' __DEBUG__ && console.log('detectBrowserLanguage: browserLocale', matchedLocale) } @@ -275,7 +265,7 @@ export function detectBrowserLanguage( localeFrom ) - const vueI18nLocale = locale || vueI18nOptions.locale + const vueI18nLocale = locale || vueI18nOptionsLocale __DEBUG__ && console.log('detectBrowserLanguage: vueI18nLocale', vueI18nLocale) // handle cookie option to prevent multiple redirects @@ -360,12 +350,12 @@ export function getLocaleDomain(locales: LocaleObject[]): string { return host } -export function getDomainFromLocale(localeCode: Locale, locales: LocaleObject[]): string | undefined { +export function getDomainFromLocale(localeCode: Locale): string | undefined { const runtimeConfig = useRuntimeConfig() const nuxtApp = useNuxtApp() // lookup the `differentDomain` origin associated with given locale. const config = runtimeConfig.public.i18n as { locales?: Record } - const lang = locales.find(locale => locale.code === localeCode) + const lang = normalizedLocales.find(locale => locale.code === localeCode) const domain = config?.locales?.[localeCode]?.domain ?? lang?.domain if (domain) { diff --git a/src/runtime/plugins/i18n.ts b/src/runtime/plugins/i18n.ts index a1dc1fa9a..a8dcac3f5 100644 --- a/src/runtime/plugins/i18n.ts +++ b/src/runtime/plugins/i18n.ts @@ -5,11 +5,10 @@ import { localeCodes, vueI18nConfigs, nuxtI18nOptions as _nuxtI18nOptions, - nuxtI18nInternalOptions, isSSG, localeLoaders, parallelPlugin, - type SimpleLocaleObject + normalizedLocales } from '#build/i18n.options.mjs' import { loadVueI18nOptions, loadInitialMessages } from '../messages' import { @@ -49,31 +48,18 @@ export default defineNuxtPlugin({ const vueI18nOptions: I18nOptions = await loadVueI18nOptions(vueI18nConfigs, useNuxtApp()) - const useCookie = nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie - const { __normalizedLocales: normalizedLocales } = nuxtI18nInternalOptions - const { - defaultLocale, - differentDomains, - skipSettingLocaleOnNavigate, - lazy, - routesNameSeparator, - defaultLocaleRouteNameSuffix, - strategy, - rootRedirect - } = nuxtI18nOptions + const _detectBrowserLanguage = nuxtI18nOptions.detectBrowserLanguage + + const useCookie = _detectBrowserLanguage && _detectBrowserLanguage.useCookie __DEBUG__ && console.log('isSSG', isSSG) __DEBUG__ && console.log('useCookie on setup', useCookie) - __DEBUG__ && console.log('defaultLocale on setup', defaultLocale) + __DEBUG__ && console.log('defaultLocale on setup', nuxtI18nOptions.defaultLocale) - nuxtI18nOptions.baseUrl = extendBaseUrl(nuxtI18nOptions.baseUrl, { - differentDomains, - localeCodeLoader: defaultLocale, - normalizedLocales - }) + nuxtI18nOptions.baseUrl = extendBaseUrl() const getLocaleFromRoute = createLocaleFromRouteGetter( localeCodes, - routesNameSeparator, - defaultLocaleRouteNameSuffix + nuxtI18nOptions.routesNameSeparator, + nuxtI18nOptions.defaultLocaleRouteNameSuffix ) vueI18nOptions.messages = vueI18nOptions.messages || {} @@ -85,12 +71,13 @@ export default defineNuxtPlugin({ let initialLocale = detectLocale( route, getLocaleFromRoute, - nuxtI18nOptions, - vueI18nOptions, - getDefaultLocale(defaultLocale), - { ssg: isSSG && strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', callType: 'setup', firstAccess: true }, - normalizedLocales, - localeCodes + vueI18nOptions.locale, + getDefaultLocale(nuxtI18nOptions.defaultLocale), + { + ssg: isSSG && nuxtI18nOptions.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', + callType: 'setup', + firstAccess: true + } ) __DEBUG__ && console.log('first detect initial locale', initialLocale) @@ -112,10 +99,7 @@ export default defineNuxtPlugin({ __DEBUG__ && console.log('final initial locale:', initialLocale) // create i18n instance - const i18n = createI18n({ - ...vueI18nOptions, - locale: initialLocale - }) + const i18n = createI18n({ ...vueI18nOptions, locale: initialLocale }) let notInitialSetup = true const isInitialLocaleSetup = (locale: Locale) => initialLocale !== locale && notInitialSetup @@ -127,7 +111,7 @@ export default defineNuxtPlugin({ * NOTE: * avoid hydration mismatch for SSG mode */ - if (isSSGModeInitialSetup() && strategy === 'no_prefix' && process.client) { + if (isSSGModeInitialSetup() && nuxtI18nOptions.strategy === 'no_prefix' && process.client) { nuxt.hook('app:mounted', async () => { __DEBUG__ && console.log('hook app:mounted') const { @@ -138,11 +122,8 @@ export default defineNuxtPlugin({ } = nuxtI18nOptions.detectBrowserLanguage ? detectBrowserLanguage( route, - nuxtI18nOptions, - nuxtI18nInternalOptions, - vueI18nOptions, + vueI18nOptions.locale, { ssg: 'ssg_setup', callType: 'setup', firstAccess: true }, - localeCodes, initialLocale ) : DefaultDetectBrowserLanguageFromResult @@ -168,23 +149,13 @@ export default defineNuxtPlugin({ context: nuxtContext, hooks: { onExtendComposer(composer: Composer) { - composer.strategy = strategy - composer.localeProperties = computed(() => { - return ( - normalizedLocales.find((l: SimpleLocaleObject) => l.code === composer.locale.value) || { - code: composer.locale.value - } - ) - }) + composer.strategy = nuxtI18nOptions.strategy + composer.localeProperties = computed( + () => normalizedLocales.find(l => l.code === composer.locale.value) || { code: composer.locale.value } + ) composer.setLocale = async (locale: string) => { const localeSetup = isInitialLocaleSetup(locale) - const [modified] = await loadAndSetLocale(locale, i18n, { - useCookie, - differentDomains, - initial: localeSetup, - skipSettingLocaleOnNavigate, - lazy - }) + const [modified] = await loadAndSetLocale(locale, i18n, localeSetup) if (modified && localeSetup) { notInitialSetup = false @@ -193,8 +164,7 @@ export default defineNuxtPlugin({ const redirectPath = detectRedirect({ route: { to: route }, targetLocale: locale, - routeLocaleGetter: getLocaleFromRoute, - nuxtI18nOptions + routeLocaleGetter: getLocaleFromRoute }) __DEBUG__ && console.log('redirectPath on setLocale', redirectPath) @@ -205,20 +175,14 @@ export default defineNuxtPlugin({ locale, route }, - { - differentDomains, - skipSettingLocaleOnNavigate, - rootRedirect, - enableNavigate: true - } + { enableNavigate: true } ) } - composer.differentDomains = differentDomains - composer.defaultLocale = defaultLocale - composer.getBrowserLocale = () => _getBrowserLocale(nuxtI18nInternalOptions) - composer.getLocaleCookie = () => _getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes }) - composer.setLocaleCookie = (locale: string) => - _setLocaleCookie(locale, nuxtI18nOptions.detectBrowserLanguage || undefined) + composer.differentDomains = nuxtI18nOptions.differentDomains + composer.defaultLocale = nuxtI18nOptions.defaultLocale + composer.getBrowserLocale = () => _getBrowserLocale() + composer.getLocaleCookie = () => _getLocaleCookie() + composer.setLocaleCookie = (locale: string) => _setLocaleCookie(locale) composer.onBeforeLanguageSwitch = (oldLocale, newLocale, initialSetup, context) => nuxt.callHook('i18n:beforeLocaleSwitch', { oldLocale, newLocale, initialSetup, context }) @@ -417,31 +381,22 @@ export default defineNuxtPlugin({ const locale = detectLocale( to, getLocaleFromRoute, - nuxtI18nOptions, - vueI18nOptions, + vueI18nOptions.locale, () => { - return getLocale(i18n) || getDefaultLocale(defaultLocale) + return getLocale(i18n) || getDefaultLocale(nuxtI18nOptions.defaultLocale) }, { - ssg: isSSGModeInitialSetup() && strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', + ssg: isSSGModeInitialSetup() && nuxtI18nOptions.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', callType: 'routing', firstAccess: routeChangeCount === 0 - }, - normalizedLocales, - localeCodes + } ) __DEBUG__ && console.log('detect locale', locale) const localeSetup = isInitialLocaleSetup(locale) __DEBUG__ && console.log('localeSetup', localeSetup) - const [modified] = await loadAndSetLocale(locale, i18n, { - useCookie, - differentDomains, - initial: localeSetup, - skipSettingLocaleOnNavigate, - lazy - }) + const [modified] = await loadAndSetLocale(locale, i18n, localeSetup) if (modified && localeSetup) { notInitialSetup = false @@ -451,26 +406,13 @@ export default defineNuxtPlugin({ route: { to, from }, targetLocale: locale, routeLocaleGetter: nuxtI18nOptions.strategy === 'no_prefix' ? () => locale : getLocaleFromRoute, - nuxtI18nOptions, calledWithRouting: true }) __DEBUG__ && console.log('redirectPath on locale-changing middleware', redirectPath) routeChangeCount++ - return navigate( - { - i18n, - redirectPath, - locale, - route: to - }, - { - differentDomains, - skipSettingLocaleOnNavigate, - rootRedirect - } - ) + return navigate({ i18n, redirectPath, locale, route: to }) }), { global: true } ) diff --git a/src/runtime/routing/compatibles/routing.ts b/src/runtime/routing/compatibles/routing.ts index f536d9ddb..680e583e5 100644 --- a/src/runtime/routing/compatibles/routing.ts +++ b/src/runtime/routing/compatibles/routing.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { isString, assign } from '@intlify/shared' import { parsePath, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo' -import { nuxtI18nInternalOptions, nuxtI18nOptions, DEFAULT_DYNAMIC_PARAMS_KEY } from '#build/i18n.options.mjs' +import { nuxtI18nOptions, DEFAULT_DYNAMIC_PARAMS_KEY } from '#build/i18n.options.mjs' import { unref, useNuxtApp, useRoute, useRouter } from '#imports' import { resolve, routeToObject } from './utils' @@ -20,8 +20,6 @@ import type { RouteLocationNormalized } from 'vue-router' -const { __normalizedLocales: normalizedLocales } = nuxtI18nInternalOptions - const RESOLVED_PREFIXED = new Set(['prefix_and_default', 'prefix_except_default']) function prefixable(options: PrefixableOptions): boolean { @@ -127,7 +125,7 @@ export function resolveRoute(route: RouteLocationRaw, locale?: Locale) { const i18n = getComposer(useNuxtApp().$i18n) const _locale = locale || getLocale(i18n) const { routesNameSeparator, defaultLocale, defaultLocaleRouteNameSuffix, strategy, trailingSlash } = nuxtI18nOptions - const prefixable = extendPrefixable(nuxtI18nOptions.differentDomains) + const prefixable = extendPrefixable() // if route parameter is a string, check if it's a path or name of route. let _route: RouteLocationPathRaw | RouteLocationNamedRaw if (isString(route)) { @@ -238,10 +236,7 @@ export function switchLocalePath( return '' } - const switchLocalePathIntercepter = extendSwitchLocalePathIntercepter( - nuxtI18nOptions.differentDomains, - normalizedLocales - ) + const switchLocalePathIntercepter = extendSwitchLocalePathIntercepter() const routeCopy = routeToObject(route) const resolvedParams = getLocalizableMetaFromDynamicParams(route)[locale] diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 19f83111e..425951e0a 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -3,12 +3,20 @@ import { joinURL, isEqual } from 'ufo' import { isString, isFunction, isArray, isObject } from '@intlify/shared' import { navigateTo, useNuxtApp, useRoute, useRuntimeConfig, useState } from '#imports' import { - nuxtI18nInternalOptions, nuxtI18nOptionsDefault, NUXT_I18N_MODULE_ID, isSSG, localeLoaders, - STRATEGIES + normalizedLocales, + nuxtI18nOptions, + type RootRedirectOptions, + type PrefixableOptions, + type SwitchLocalePathIntercepter, + type BaseUrlResolveHandler, + type I18nHeadOptions, + type LocaleObject, + STRATEGIES, + type SeoAttributesOptions } from '#build/i18n.options.mjs' import { detectBrowserLanguage, @@ -23,20 +31,8 @@ import { } from './internal' import { loadLocale, makeFallbackLocaleCodes } from './messages' -import type { I18n, I18nOptions, Locale, FallbackLocale } from 'vue-i18n' +import type { I18n, Locale, FallbackLocale } from 'vue-i18n' import type { NuxtApp } from '#app' -import type { - NuxtI18nOptions, - DetectBrowserLanguageOptions, - RootRedirectOptions, - LocaleObject, - PrefixableOptions, - SwitchLocalePathIntercepter, - BaseUrlResolveHandler, - I18nHeadOptions, - SeoAttributesOptions -} from '#build/i18n.options.mjs' -import type { DeepRequired } from 'ts-essentials' import type { DetectLocaleContext } from './internal' import type { HeadSafe } from '@unhead/vue' import { useLocaleRoute, useRouteBaseName, useSwitchLocalePath } from '#i18n' @@ -87,20 +83,18 @@ export async function finalizePendingLocaleChange(i18n: I18n) { return callVueI18nInterfaces(i18n, 'finalizePendingLocaleChange') } -export async function loadAndSetLocale( +export async function loadAndSetLocale( newLocale: string, i18n: I18n, - { - useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie, - skipSettingLocaleOnNavigate = nuxtI18nOptionsDefault.skipSettingLocaleOnNavigate, - differentDomains = nuxtI18nOptionsDefault.differentDomains, - initial = false, - lazy = false - }: Pick & - Pick, 'lazy' | 'skipSettingLocaleOnNavigate' | 'differentDomains'> & { - initial?: boolean - } = {} + initial: boolean = false ): Promise<[boolean, string]> { + const _differentDomains = nuxtI18nOptions.differentDomains ?? nuxtI18nOptionsDefault.differentDomains + const skipSettingLocaleOnNavigate = + nuxtI18nOptions.skipSettingLocaleOnNavigate ?? nuxtI18nOptionsDefault.skipSettingLocaleOnNavigate + const lazy = nuxtI18nOptions.lazy ?? nuxtI18nOptionsDefault.lazy + const useCookie = + (nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie) ?? + nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie const nuxtApp = useNuxtApp() let ret = false const oldLocale = getLocale(i18n) @@ -110,7 +104,7 @@ export async function loadAndSetLocale( } // abort if different domains option enabled - if (!initial && differentDomains) { + if (!initial && _differentDomains) { return [ret, oldLocale] } @@ -156,17 +150,14 @@ export async function loadAndSetLocale( type LocaleLoader = () => Locale -export function detectLocale( +export function detectLocale( route: string | RouteLocationNormalized | RouteLocationNormalizedLoaded, routeLocaleGetter: ReturnType, - nuxtI18nOptions: DeepRequired>, - vueI18nOptions: I18nOptions, + vueI18nOptionsLocale: Locale | undefined, initialLocaleLoader: Locale | LocaleLoader, - detectLocaleContext: DetectLocaleContext, - normalizedLocales: LocaleObject[], - localeCodes: string[] = [] + detectLocaleContext: DetectLocaleContext ) { - const { strategy, defaultLocale, differentDomains } = nuxtI18nOptions + const { strategy, defaultLocale, differentDomains, detectBrowserLanguage: _detectBrowserLanguage } = nuxtI18nOptions const initialLocale = isFunction(initialLocaleLoader) ? initialLocaleLoader() : initialLocaleLoader __DEBUG__ && console.log('detectLocale: initialLocale -', initialLocale) @@ -174,22 +165,13 @@ export function detectLocale( const { ssg, callType, firstAccess } = detectLocaleContext __DEBUG__ && console.log('detectLocale: (ssg, callType, firstAccess) - ', ssg, callType, firstAccess) - // prettier-ignore const { locale: browserLocale, stat, reason, from - } = nuxtI18nOptions.detectBrowserLanguage - ? detectBrowserLanguage( - route, - nuxtI18nOptions, - nuxtI18nInternalOptions, - vueI18nOptions, - detectLocaleContext, - localeCodes, - initialLocale - ) + } = _detectBrowserLanguage + ? detectBrowserLanguage(route, vueI18nOptionsLocale, detectLocaleContext, initialLocale) : DefaultDetectBrowserLanguageFromResult __DEBUG__ && console.log( @@ -220,7 +202,7 @@ export function detectLocale( } else if (strategy !== 'no_prefix') { finalLocale = routeLocaleGetter(route) } else { - if (!nuxtI18nOptions.detectBrowserLanguage) { + if (!_detectBrowserLanguage) { finalLocale = initialLocale } } @@ -230,10 +212,10 @@ export function detectLocale( console.log( 'detectLocale: finaleLocale second (finaleLocale, detectBrowserLanguage) -', finalLocale, - nuxtI18nOptions.detectBrowserLanguage + _detectBrowserLanguage ) - if (!finalLocale && nuxtI18nOptions.detectBrowserLanguage && nuxtI18nOptions.detectBrowserLanguage.useCookie) { - finalLocale = getLocaleCookie({ ...nuxtI18nOptions.detectBrowserLanguage, localeCodes }) || '' + if (!finalLocale && _detectBrowserLanguage && _detectBrowserLanguage.useCookie) { + finalLocale = getLocaleCookie() || '' } __DEBUG__ && console.log('detectLocale: finalLocale last (finalLocale, defaultLocale) -', finalLocale, defaultLocale) @@ -245,11 +227,10 @@ export function detectLocale( return finalLocale } -export function detectRedirect({ +export function detectRedirect({ route, targetLocale, routeLocaleGetter, - nuxtI18nOptions, calledWithRouting = false }: { route: { @@ -258,7 +239,6 @@ export function detectRedirect({ } targetLocale: Locale routeLocaleGetter: ReturnType - nuxtI18nOptions: DeepRequired> calledWithRouting?: boolean }): string { const nuxtApp = useNuxtApp() @@ -334,19 +314,14 @@ function _navigate(redirectPath: string, status: number) { return navigateTo(redirectPath, { redirectCode: status }) } -export async function navigate( +export async function navigate( args: NavigateArgs, - { - status = 302, - rootRedirect = nuxtI18nOptionsDefault.rootRedirect, - differentDomains = nuxtI18nOptionsDefault.differentDomains, - skipSettingLocaleOnNavigate = nuxtI18nOptionsDefault.skipSettingLocaleOnNavigate, - enableNavigate = false - }: { - status?: number - enableNavigate?: boolean - } & Pick, 'skipSettingLocaleOnNavigate' | 'differentDomains' | 'rootRedirect'> = {} + { status = 302, enableNavigate = false }: { status?: number; enableNavigate?: boolean } = {} ) { + const rootRedirect = nuxtI18nOptions.rootRedirect ?? nuxtI18nOptionsDefault.rootRedirect + const differentDomains = nuxtI18nOptions.differentDomains ?? nuxtI18nOptionsDefault.differentDomains + const skipSettingLocaleOnNavigate = + nuxtI18nOptions.skipSettingLocaleOnNavigate ?? nuxtI18nOptionsDefault.skipSettingLocaleOnNavigate const { i18n, locale, route } = args let { redirectPath } = args @@ -422,20 +397,17 @@ export function injectNuxtHelpers(nuxt: NuxtApp, i18n: I18n) { } // override prefix for route path, support domain -export function extendPrefixable(differentDomains: boolean) { - return (options: PrefixableOptions): boolean => { - return DefaultPrefixable(options) && !differentDomains +export function extendPrefixable() { + return (opts: PrefixableOptions): boolean => { + return DefaultPrefixable(opts) && !nuxtI18nOptions.differentDomains } } // override switch locale path intercepter, support domain -export function extendSwitchLocalePathIntercepter( - differentDomains: boolean, - normalizedLocales: LocaleObject[] -): SwitchLocalePathIntercepter { +export function extendSwitchLocalePathIntercepter(): SwitchLocalePathIntercepter { return (path: string, locale: Locale): string => { - if (differentDomains) { - const domain = getDomainFromLocale(locale, normalizedLocales) + if (nuxtI18nOptions.differentDomains) { + const domain = getDomainFromLocale(locale) __DEBUG__ && console.log('extendSwitchLocalePathIntercepter: domain -> ', domain, ' path -> ', path) if (domain) { return joinURL(domain, path) @@ -448,26 +420,22 @@ export function extendSwitchLocalePathIntercepter( } } -export function extendBaseUrl( - baseUrl: string | BaseUrlResolveHandler, - options: Pick>, 'differentDomains'> & { - localeCodeLoader: Locale | LocaleLoader - normalizedLocales: LocaleObject[] - } -): BaseUrlResolveHandler { +export function extendBaseUrl(): BaseUrlResolveHandler { return (): string => { const ctx = useNuxtApp() const runtimeConfig = useRuntimeConfig() + const baseUrl = nuxtI18nOptions.baseUrl + if (isFunction(baseUrl)) { const baseUrlResult = baseUrl(ctx) __DEBUG__ && console.log('baseUrl: using localeLoader function -', baseUrlResult) return baseUrlResult } - const { differentDomains, localeCodeLoader, normalizedLocales } = options + const localeCodeLoader = nuxtI18nOptions.defaultLocale const localeCode = isFunction(localeCodeLoader) ? localeCodeLoader() : localeCodeLoader - if (differentDomains && localeCode) { - const domain = getDomainFromLocale(localeCode, normalizedLocales) + if (nuxtI18nOptions.differentDomains && localeCode) { + const domain = getDomainFromLocale(localeCode) if (domain) { __DEBUG__ && console.log('baseUrl: using differentDomains -', domain) return domain diff --git a/src/template.ts b/src/template.ts index fa6e51641..42644f4d7 100644 --- a/src/template.ts +++ b/src/template.ts @@ -9,15 +9,14 @@ import { DEFAULT_DETECTION_DIRECTION, DEFAULT_DYNAMIC_PARAMS_KEY, DEFAULT_LOCALE_ROUTE_NAME_SUFFIX, - DEFAULT_STRATEGY + DEFAULT_STRATEGY, + NUXT_I18N_MODULE_ID } from './constants' -import type { SimpleLocaleObject } from './types' +import type { LocaleObject } from './types' export type TemplateNuxtI18nOptions = { - NUXT_I18N_MODULE_ID: string localeCodes: string[] - nuxtI18nOptionsDefault: typeof DEFAULT_OPTIONS - nuxtI18nInternalOptions: { __normalizedLocales: SimpleLocaleObject[] } + normalizedLocales: LocaleObject[] dev: boolean isSSG: boolean parallelPlugin: boolean @@ -49,11 +48,11 @@ export const vueI18nConfigs = [ export const nuxtI18nOptions = ${JSON.stringify(options.nuxtI18nOptions, null, 2)} -export const nuxtI18nOptionsDefault = ${JSON.stringify(options.nuxtI18nOptionsDefault, null, 2)} +export const nuxtI18nOptionsDefault = ${JSON.stringify(DEFAULT_OPTIONS, null, 2)} -export const nuxtI18nInternalOptions = ${JSON.stringify(options.nuxtI18nInternalOptions, null, 2)} +export const normalizedLocales = ${JSON.stringify(options.normalizedLocales, null, 2)} -export const NUXT_I18N_MODULE_ID = "${options.NUXT_I18N_MODULE_ID}" +export const NUXT_I18N_MODULE_ID = "${NUXT_I18N_MODULE_ID}" export const parallelPlugin = ${options.parallelPlugin} export const isSSG = ${options.isSSG} diff --git a/src/types.ts b/src/types.ts index 34fef0f1a..176e873a3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -123,10 +123,6 @@ export type NuxtI18nOptions = { | 'trailingSlash' > -export type NuxtI18nInternalOptions = { - __normalizedLocales?: SimpleLocaleObject[] -} - export type VueI18nConfig = () => Promise<{ default: I18nOptions | (() => I18nOptions | Promise) }> /* eslint-disable @typescript-eslint/no-explicit-any */