From b0016471c617ece151ac1d2f3195f3bd4b0b3bc7 Mon Sep 17 00:00:00 2001 From: Bobbie Goede Date: Thu, 7 Mar 2024 11:05:19 +0100 Subject: [PATCH] refactor: pass generated options through `runtimeConfig` (#2828) --- src/constants.ts | 4 +- src/gen.ts | 2 +- src/module.ts | 32 +++++++++++++++- src/options.d.ts | 2 - src/runtime/composables/index.ts | 2 +- src/runtime/internal.ts | 26 ++++++------- src/runtime/plugins/i18n.ts | 43 +++++++++++---------- src/runtime/routing/compatibles/head.ts | 9 ++--- src/runtime/routing/compatibles/routing.ts | 19 +++++----- src/runtime/routing/extends/router.ts | 5 ++- src/runtime/server/plugin.ts | 23 ++++++----- src/runtime/utils.ts | 44 +++++++++++----------- src/types.ts | 2 +- 13 files changed, 117 insertions(+), 96 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 060005d52..f327e198b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -54,7 +54,7 @@ export const DEFAULT_OPTIONS = { strategy: STRATEGY_PREFIX_EXCEPT_DEFAULT, lazy: false, langDir: null, - rootRedirect: null, + rootRedirect: undefined, detectBrowserLanguage: { alwaysRedirect: false, cookieCrossOrigin: false, @@ -87,5 +87,3 @@ export const JS_EXTENSIONS = ['.js', '.cjs', '.mjs'] export const EXECUTABLE_EXTENSIONS = [...JS_EXTENSIONS, ...TS_EXTENSIONS] export const NULL_HASH = '00000000' as const - -export type NuxtI18nOptionsDefault = typeof DEFAULT_OPTIONS diff --git a/src/gen.ts b/src/gen.ts index 7d72c66b1..4836bc5f8 100644 --- a/src/gen.ts +++ b/src/gen.ts @@ -32,7 +32,7 @@ const generateVueI18nConfiguration = (config: Required, i ) } -function simplifyLocaleOptions(nuxt: Nuxt, options: NuxtI18nOptions) { +export function simplifyLocaleOptions(nuxt: Nuxt, options: NuxtI18nOptions) { const isLocaleObjectsArray = (locales?: string[] | LocaleObject[]) => locales?.some(x => typeof x !== 'string') const hasLocaleObjects = diff --git a/src/module.ts b/src/module.ts index 78ff4b091..8d39a5f90 100644 --- a/src/module.ts +++ b/src/module.ts @@ -17,7 +17,7 @@ import { setupAlias } from './alias' import { setupPages } from './pages' import { setupNitro } from './nitro' import { extendBundler } from './bundler' -import { generateI18nPageTypes, generateI18nTypes, generateLoaderOptions } from './gen' +import { generateI18nPageTypes, generateI18nTypes, generateLoaderOptions, simplifyLocaleOptions } from './gen' import { NUXT_I18N_MODULE_ID, DEFAULT_OPTIONS, @@ -140,8 +140,20 @@ export default defineNuxtModule({ */ // for public + // @ts-expect-error generated type nuxt.options.runtimeConfig.public.i18n = defu(nuxt.options.runtimeConfig.public.i18n, { baseUrl: options.baseUrl, + defaultLocale: options.defaultLocale, + defaultDirection: options.defaultDirection, + strategy: options.strategy, + lazy: options.lazy, + rootRedirect: options.rootRedirect, + routesNameSeparator: options.routesNameSeparator, + defaultLocaleRouteNameSuffix: options.defaultLocaleRouteNameSuffix, + skipSettingLocaleOnNavigate: options.skipSettingLocaleOnNavigate, + differentDomains: options.differentDomains, + trailingSlash: options.trailingSlash, + configLocales: options.locales, locales: options.locales.reduce( (obj, locale) => { if (typeof locale === 'string') { @@ -223,6 +235,9 @@ export default defineNuxtModule({ }) } + // @ts-expect-error type error + nuxt.options.runtimeConfig.public.i18n.configLocales = simplifyLocaleOptions(nuxt, defu({}, options)) + addTemplate({ filename: NUXT_I18N_TEMPLATE_OPTIONS_KEY, write: true, @@ -337,7 +352,20 @@ export default defineNuxtModule({ export interface ModuleOptions extends NuxtI18nOptions {} export interface ModulePublicRuntimeConfig { - i18n: Required, 'baseUrl' | 'detectBrowserLanguage'>> + i18n: Pick, 'baseUrl' | 'rootRedirect'> & + Pick< + Required>, + | 'differentDomains' + | 'skipSettingLocaleOnNavigate' + | 'defaultLocale' + | 'lazy' + | 'defaultDirection' + | 'detectBrowserLanguage' + | 'strategy' + | 'routesNameSeparator' + | 'defaultLocaleRouteNameSuffix' + | 'trailingSlash' + > & { configLocales: NonNullable>['locales']> } } export interface ModuleHooks { diff --git a/src/options.d.ts b/src/options.d.ts index 5a32bb6bc..504642d45 100644 --- a/src/options.d.ts +++ b/src/options.d.ts @@ -1,6 +1,5 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars import type { NuxtI18nOptions, VueI18nConfig } from './types' -import type { NuxtI18nOptionsDefault } from './constants' import type { DeepRequired } from 'ts-essentials' export type * from './types' @@ -30,5 +29,4 @@ export const NUXT_I18N_MODULE_ID = '' export const DEFAULT_DYNAMIC_PARAMS_KEY: string export const DEFAULT_COOKIE_KEY: string -export { NuxtI18nOptionsDefault } export { NuxtI18nOptions, DetectBrowserLanguageOptions, RootRedirectOptions } from './types' diff --git a/src/runtime/composables/index.ts b/src/runtime/composables/index.ts index c38ebdcb1..ce5187260 100644 --- a/src/runtime/composables/index.ts +++ b/src/runtime/composables/index.ts @@ -202,7 +202,7 @@ export type RouteBaseNameFunction = (givenRoute?: RouteLocationNormalizedLoaded) * @public */ export function useRouteBaseName(): RouteBaseNameFunction { - return getRouteBaseName + return wrapComposable(getRouteBaseName) } /** diff --git a/src/runtime/internal.ts b/src/runtime/internal.ts index 912b1052c..a03fb8b0f 100644 --- a/src/runtime/internal.ts +++ b/src/runtime/internal.ts @@ -11,14 +11,7 @@ import { useNuxtApp, unref } from '#imports' -import { - NUXT_I18N_MODULE_ID, - DEFAULT_COOKIE_KEY, - isSSG, - localeCodes, - nuxtI18nOptions, - normalizedLocales -} from '#build/i18n.options.mjs' +import { NUXT_I18N_MODULE_ID, DEFAULT_COOKIE_KEY, isSSG, localeCodes, normalizedLocales } from '#build/i18n.options.mjs' import { findBrowserLocale, getLocalesRegex, getI18nTarget } from './routing/utils' import { initCommonComposableOptions, type CommonComposableOptions } from './utils' @@ -26,6 +19,7 @@ import type { Locale } from 'vue-i18n' import type { DetectBrowserLanguageOptions, LocaleObject } from '#build/i18n.options.mjs' import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router' import type { CookieRef } from 'nuxt/app' +import type { ModulePublicRuntimeConfig } from '../module' export function formatMessage(message: string) { return NUXT_I18N_MODULE_ID + ' ' + message @@ -128,9 +122,14 @@ export function getLocaleCookie( } const localeCode: string | undefined = cookieRef.value ?? undefined - __DEBUG__ && console.log(`getLocaleCookie cookie (${process.client ? 'client' : 'server'}) -`, localeCode) + if (localeCode == null) { + __DEBUG__ && console.log(`getLocaleCookie (${process.client ? 'client' : 'server'}) - none`) + return + } - if (localeCode && localeCodes.includes(localeCode)) { + if (localeCodes.includes(localeCode)) { + __DEBUG__ && + console.log(`getLocaleCookie (${process.client ? 'client' : 'server'}) - locale from cookie: `, localeCode) return localeCode } } @@ -183,7 +182,7 @@ export function detectBrowserLanguage( detectLocaleContext: DetectLocaleContext, locale: Locale = '' ): DetectBrowserLanguageFromResult { - const { strategy } = nuxtI18nOptions + const { strategy } = useRuntimeConfig().public.i18n const { ssg, callType, firstAccess, localeCookie } = detectLocaleContext __DEBUG__ && console.log('detectBrowserLanguage: (ssg, callType, firstAccess) - ', ssg, callType, firstAccess) @@ -376,8 +375,9 @@ export function getDomainFromLocale(localeCode: Locale): string | undefined { /* eslint-enable @typescript-eslint/no-explicit-any */ -export const runtimeDetectBrowserLanguage = () => { - const opts = useRuntimeConfig().public.i18n +export const runtimeDetectBrowserLanguage = ( + opts: ModulePublicRuntimeConfig['i18n'] = useRuntimeConfig().public.i18n +) => { if (opts?.detectBrowserLanguage === false) return false return opts?.detectBrowserLanguage diff --git a/src/runtime/plugins/i18n.ts b/src/runtime/plugins/i18n.ts index 5913261d7..dd8a320b0 100644 --- a/src/runtime/plugins/i18n.ts +++ b/src/runtime/plugins/i18n.ts @@ -4,7 +4,6 @@ import { defineNuxtPlugin, useRoute, addRouteMiddleware, defineNuxtRouteMiddlewa import { localeCodes, vueI18nConfigs, - nuxtI18nOptions as _nuxtI18nOptions, isSSG, localeLoaders, parallelPlugin, @@ -53,14 +52,15 @@ export default defineNuxtPlugin({ const nuxtContext = nuxt as unknown as NuxtApp // Fresh copy per request to prevent reusing mutated options - const nuxtI18nOptions = { ..._nuxtI18nOptions } - nuxtI18nOptions.baseUrl = extendBaseUrl() + const runtimeI18n = { ...nuxtContext.$config.public.i18n } + // @ts-expect-error type incompatible + runtimeI18n.baseUrl = extendBaseUrl() const _detectBrowserLanguage = runtimeDetectBrowserLanguage() __DEBUG__ && console.log('isSSG', isSSG) __DEBUG__ && console.log('useCookie on setup', _detectBrowserLanguage && _detectBrowserLanguage.useCookie) - __DEBUG__ && console.log('defaultLocale on setup', nuxtI18nOptions.defaultLocale) + __DEBUG__ && console.log('defaultLocale on setup', runtimeI18n.defaultLocale) const vueI18nOptions: I18nOptions = await loadVueI18nOptions(vueI18nConfigs, useNuxtApp()) vueI18nOptions.messages = vueI18nOptions.messages || {} @@ -75,14 +75,14 @@ export default defineNuxtPlugin({ route, getLocaleFromRoute, vueI18nOptions.locale, - getDefaultLocale(nuxtI18nOptions.defaultLocale), + getDefaultLocale(runtimeI18n.defaultLocale), { - ssg: isSSG && nuxtI18nOptions.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', + ssg: isSSG && runtimeI18n.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', callType: 'setup', firstAccess: true, localeCookie }, - _detectBrowserLanguage + runtimeI18n ) __DEBUG__ && console.log('first detect initial locale', initialLocale) @@ -90,8 +90,8 @@ export default defineNuxtPlugin({ vueI18nOptions.messages = await loadInitialMessages(vueI18nOptions.messages, localeLoaders, { localeCodes, initialLocale, - lazy: nuxtI18nOptions.lazy, - defaultLocale: nuxtI18nOptions.defaultLocale, + lazy: runtimeI18n.lazy, + defaultLocale: runtimeI18n.defaultLocale, fallbackLocale: vueI18nOptions.fallbackLocale }) @@ -116,7 +116,7 @@ export default defineNuxtPlugin({ * NOTE: * avoid hydration mismatch for SSG mode */ - if (isSSGModeInitialSetup() && nuxtI18nOptions.strategy === 'no_prefix' && process.client) { + if (isSSGModeInitialSetup() && runtimeI18n.strategy === 'no_prefix' && process.client) { nuxt.hook('app:mounted', async () => { __DEBUG__ && console.log('hook app:mounted') const { @@ -147,20 +147,19 @@ export default defineNuxtPlugin({ // extend i18n instance extendI18n(i18n, { - // @ts-ignore - locales: nuxtI18nOptions.locales, + locales: runtimeI18n.configLocales, localeCodes, - baseUrl: nuxtI18nOptions.baseUrl, + baseUrl: runtimeI18n.baseUrl, context: nuxtContext, hooks: { onExtendComposer(composer: Composer) { - composer.strategy = nuxtI18nOptions.strategy + composer.strategy = runtimeI18n.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, localeSetup) + const [modified] = await loadAndSetLocale(locale, i18n, runtimeI18n, localeSetup) if (modified && localeSetup) { notInitialSetup = false @@ -194,8 +193,8 @@ export default defineNuxtPlugin({ const setter = (locale: Locale, message: Record) => mergeLocaleMessage(i18n, locale, message) await loadLocale(locale, localeLoaders, setter) } - composer.differentDomains = nuxtI18nOptions.differentDomains - composer.defaultLocale = nuxtI18nOptions.defaultLocale + composer.differentDomains = runtimeI18n.differentDomains + composer.defaultLocale = runtimeI18n.defaultLocale composer.getBrowserLocale = () => _getBrowserLocale() composer.getLocaleCookie = () => _getLocaleCookie(localeCookie, _detectBrowserLanguage) composer.setLocaleCookie = (locale: string) => _setLocaleCookie(localeCookie, locale, _detectBrowserLanguage) @@ -405,22 +404,22 @@ export default defineNuxtPlugin({ getLocaleFromRoute, vueI18nOptions.locale, () => { - return getLocale(i18n) || getDefaultLocale(nuxtI18nOptions.defaultLocale) + return getLocale(i18n) || getDefaultLocale(runtimeI18n.defaultLocale) }, { - ssg: isSSGModeInitialSetup() && nuxtI18nOptions.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', + ssg: isSSGModeInitialSetup() && runtimeI18n.strategy === 'no_prefix' ? 'ssg_ignore' : 'normal', callType: 'routing', firstAccess: routeChangeCount === 0, localeCookie }, - _detectBrowserLanguage + runtimeI18n ) __DEBUG__ && console.log('detect locale', locale) const localeSetup = isInitialLocaleSetup(locale) __DEBUG__ && console.log('localeSetup', localeSetup) - const [modified] = await loadAndSetLocale(locale, i18n, localeSetup) + const [modified] = await loadAndSetLocale(locale, i18n, runtimeI18n, localeSetup) if (modified && localeSetup) { notInitialSetup = false @@ -430,7 +429,7 @@ export default defineNuxtPlugin({ detectRedirect({ route: { to, from }, targetLocale: locale, - routeLocaleGetter: nuxtI18nOptions.strategy === 'no_prefix' ? () => locale : getLocaleFromRoute, + routeLocaleGetter: runtimeI18n.strategy === 'no_prefix' ? () => locale : getLocaleFromRoute, calledWithRouting: true }) ) diff --git a/src/runtime/routing/compatibles/head.ts b/src/runtime/routing/compatibles/head.ts index 161f2863c..41c7a4149 100644 --- a/src/runtime/routing/compatibles/head.ts +++ b/src/runtime/routing/compatibles/head.ts @@ -1,5 +1,4 @@ -import { unref, useNuxtApp } from '#imports' -import { nuxtI18nOptions } from '#build/i18n.options.mjs' +import { unref, useNuxtApp, useRuntimeConfig } from '#imports' import { getComposer, getLocale, getLocales, getNormalizedLocales } from '../utils' import { getRouteBaseName, localeRoute, switchLocalePath } from './routing' @@ -25,7 +24,7 @@ export function localeHead( identifierAttribute: idAttribute = 'hid' }: I18nHeadOptions ): I18nHeadMetaInfo { - const { defaultDirection } = nuxtI18nOptions + const { defaultDirection } = useRuntimeConfig().public.i18n const i18n = getComposer(common.i18n) const metaObject: Required = { @@ -83,7 +82,7 @@ export function getHreflangLinks( idAttribute: NonNullable ) { const baseUrl = getBaseUrl() - const { defaultLocale, strategy } = nuxtI18nOptions + const { defaultLocale, strategy } = useRuntimeConfig().public.i18n const links: MetaAttrs[] = [] if (strategy === 'no_prefix') return links @@ -138,7 +137,7 @@ export function getCanonicalUrl( seoAttributes: I18nHeadOptions['addSeoAttributes'] ) { const route = common.router.currentRoute.value - const currentRoute = localeRoute(common, { ...route, name: getRouteBaseName(route) }) + const currentRoute = localeRoute(common, { ...route, name: getRouteBaseName(common, route) }) if (!currentRoute) return '' let href = toAbsoluteUrl(currentRoute.path, baseUrl) diff --git a/src/runtime/routing/compatibles/routing.ts b/src/runtime/routing/compatibles/routing.ts index 965ec0f47..54e3a47fa 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 { hasProtocol, parsePath, parseQuery, withTrailingSlash, withoutTrailingSlash } from 'ufo' -import { nuxtI18nOptions, DEFAULT_DYNAMIC_PARAMS_KEY } from '#build/i18n.options.mjs' +import { DEFAULT_DYNAMIC_PARAMS_KEY } from '#build/i18n.options.mjs' import { unref } from '#imports' import { resolve, routeToObject } from './utils' @@ -47,8 +47,8 @@ export const DefaultPrefixable = prefixable * * @public */ -export function getRouteBaseName(givenRoute?: RouteLocation): string | undefined { - const { routesNameSeparator } = nuxtI18nOptions +export function getRouteBaseName(common: CommonComposableOptions, givenRoute?: RouteLocation): string | undefined { + const { routesNameSeparator } = common.runtimeConfig.public.i18n const route = unref(givenRoute) if (route == null || !route.name) { return @@ -131,8 +131,9 @@ export function localeLocation( export function resolveRoute(common: CommonComposableOptions, route: RouteLocationRaw, locale: Locale | undefined) { const { router, i18n } = common const _locale = locale || getLocale(i18n) - const { routesNameSeparator, defaultLocale, defaultLocaleRouteNameSuffix, strategy, trailingSlash } = nuxtI18nOptions - const prefixable = extendPrefixable() + const { routesNameSeparator, defaultLocale, defaultLocaleRouteNameSuffix, strategy, trailingSlash } = + common.runtimeConfig.public.i18n + const prefixable = extendPrefixable(common.runtimeConfig) // if route parameter is a string, check if it's a path or name of route. let _route: RouteLocationPathRaw | RouteLocationNamedRaw if (isString(route)) { @@ -158,7 +159,7 @@ export function resolveRoute(common: CommonComposableOptions, route: RouteLocati const resolvedRoute = resolve(common, localizedRoute, strategy, _locale) // @ts-ignore - const resolvedRouteName = getRouteBaseName(resolvedRoute) + const resolvedRouteName = getRouteBaseName(common, resolvedRoute) if (isString(resolvedRouteName)) { localizedRoute = { name: getLocaleRouteName(resolvedRouteName, _locale, { @@ -187,7 +188,7 @@ export function resolveRoute(common: CommonComposableOptions, route: RouteLocati } } else { if (!localizedRoute.name && !('path' in localizedRoute)) { - localizedRoute.name = getRouteBaseName(router.currentRoute.value) + localizedRoute.name = getRouteBaseName(common, router.currentRoute.value) } localizedRoute.name = getLocaleRouteName(localizedRoute.name, _locale, { @@ -238,13 +239,13 @@ export function switchLocalePath( _route?: RouteLocationNormalized | RouteLocationNormalizedLoaded ): string { const route = _route ?? common.router.currentRoute.value - const name = getRouteBaseName(route) + const name = getRouteBaseName(common, route) if (!name) { return '' } - const switchLocalePathIntercepter = extendSwitchLocalePathIntercepter() + const switchLocalePathIntercepter = extendSwitchLocalePathIntercepter(common.runtimeConfig) const routeCopy = routeToObject(route) const resolvedParams = getLocalizableMetaFromDynamicParams(route)[locale] diff --git a/src/runtime/routing/extends/router.ts b/src/runtime/routing/extends/router.ts index eb00164c9..3f90a4b90 100644 --- a/src/runtime/routing/extends/router.ts +++ b/src/runtime/routing/extends/router.ts @@ -1,11 +1,12 @@ import { isString, isObject } from '@intlify/shared' import { getLocalesRegex } from '../utils' -import { localeCodes, nuxtI18nOptions } from '#build/i18n.options.mjs' +import { localeCodes } from '#build/i18n.options.mjs' import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router' +import { useRuntimeConfig } from 'nuxt/app' export function createLocaleFromRouteGetter() { - const { routesNameSeparator, defaultLocaleRouteNameSuffix } = nuxtI18nOptions + const { routesNameSeparator, defaultLocaleRouteNameSuffix } = useRuntimeConfig().public.i18n const localesPattern = `(${localeCodes.join('|')})` const defaultSuffixPattern = `(?:${routesNameSeparator}${defaultLocaleRouteNameSuffix})?` const regexpName = new RegExp(`${routesNameSeparator}${localesPattern}${defaultSuffixPattern}$`, 'i') diff --git a/src/runtime/server/plugin.ts b/src/runtime/server/plugin.ts index 8cb501591..f50a18dfe 100644 --- a/src/runtime/server/plugin.ts +++ b/src/runtime/server/plugin.ts @@ -1,32 +1,33 @@ +import { useRuntimeConfig } from '#imports' import { defineI18nMiddleware } from '@intlify/h3' -import { nuxtI18nOptions, localeCodes, vueI18nConfigs, localeLoaders } from '#internal/i18n/options.mjs' +import { localeCodes, vueI18nConfigs, localeLoaders } from '#internal/i18n/options.mjs' +import { defineNitroPlugin } from 'nitropack/dist/runtime/plugin' // @ts-ignore import { localeDetector as _localeDetector } from '#internal/i18n/locale.detector.mjs' import { loadVueI18nOptions, loadInitialMessages, makeFallbackLocaleCodes, loadAndSetLocaleMessages } from '../messages' -import type { NitroAppPlugin } from 'nitropack' import type { H3Event } from 'h3' -import type { NuxtApp } from 'nuxt/app' import type { Locale, FallbackLocale, DefineLocaleMessage } from 'vue-i18n' import type { CoreContext } from '@intlify/h3' +import type { NuxtApp } from 'nuxt/app' const nuxtMock: { runWithContext: NuxtApp['runWithContext'] } = { runWithContext: async fn => await fn() } -export const nitroPlugin: NitroAppPlugin = async nitro => { +export default defineNitroPlugin(async nitro => { // `defineI18nMiddleware` options (internally, options passed to`createCoreContext` in intlify / core) are compatible with vue-i18n options const options = (await loadVueI18nOptions(vueI18nConfigs, nuxtMock)) as any // eslint-disable-line @typescript-eslint/no-explicit-any options.messages = options.messages || {} const fallbackLocale = (options.fallbackLocale = options.fallbackLocale ?? false) as FallbackLocale - const { defaultLocale, lazy } = nuxtI18nOptions - const initialLocale = defaultLocale || options.locale || 'en-US' + const runtimeI18n = useRuntimeConfig().public.i18n + const initialLocale = runtimeI18n.defaultLocale || options.locale || 'en-US' // load initial locale messages for intlify/h3 options.messages = await loadInitialMessages(options.messages, localeLoaders, { localeCodes, initialLocale, - lazy: nuxtI18nOptions.lazy, - defaultLocale: nuxtI18nOptions.defaultLocale, + lazy: runtimeI18n.lazy, + defaultLocale: runtimeI18n.defaultLocale, fallbackLocale: options.fallbackLocale }) @@ -35,7 +36,7 @@ export const nitroPlugin: NitroAppPlugin = async nitro => { i18nContext: CoreContext ): Promise => { const locale = _localeDetector(event, { defaultLocale: initialLocale, fallbackLocale: options.fallbackLocale }) - if (lazy) { + if (runtimeI18n.lazy) { if (fallbackLocale) { const fallbackLocales = makeFallbackLocaleCodes(fallbackLocale, [locale]) await Promise.all( @@ -54,6 +55,4 @@ export const nitroPlugin: NitroAppPlugin = async nitro => { nitro.hooks.hook('request', onRequest) nitro.hooks.hook('afterResponse', onAfterResponse) -} - -export default nitroPlugin +}) diff --git a/src/runtime/utils.ts b/src/runtime/utils.ts index 51a3215c7..7d4ca7329 100644 --- a/src/runtime/utils.ts +++ b/src/runtime/utils.ts @@ -7,13 +7,11 @@ import { isSSG, localeLoaders, normalizedLocales, - nuxtI18nOptions, type RootRedirectOptions, type PrefixableOptions, type SwitchLocalePathIntercepter, type BaseUrlResolveHandler, - type LocaleObject, - type DetectBrowserLanguageOptions + type LocaleObject } from '#build/i18n.options.mjs' import { wrapComposable, @@ -46,6 +44,7 @@ import type { HeadSafe } from '@unhead/vue' import type { createLocaleFromRouteGetter } from './routing/extends/router' import type { RouteLocationNormalized, RouteLocationNormalizedLoaded } from 'vue-router' import type { RuntimeConfig } from '@nuxt/schema' +import type { ModulePublicRuntimeConfig } from '../module' export function _setLocale(i18n: I18n, locale: Locale) { return callVueI18nInterfaces(i18n, 'setLocale', locale) @@ -103,10 +102,11 @@ export function initCommonComposableOptions(i18n?: I18n): CommonComposableOption export async function loadAndSetLocale( newLocale: string, i18n: I18n, + runtimeI18n: ModulePublicRuntimeConfig['i18n'], initial: boolean = false ): Promise<[boolean, string]> { - const { differentDomains, skipSettingLocaleOnNavigate, lazy } = nuxtI18nOptions - const opts = runtimeDetectBrowserLanguage() + const { differentDomains, skipSettingLocaleOnNavigate, lazy } = runtimeI18n + const opts = runtimeDetectBrowserLanguage(runtimeI18n) const nuxtApp = useNuxtApp() let ret = false @@ -169,9 +169,10 @@ export function detectLocale( vueI18nOptionsLocale: Locale | undefined, initialLocaleLoader: Locale | LocaleLoader, detectLocaleContext: DetectLocaleContext, - _detectBrowserLanguage: false | DetectBrowserLanguageOptions + runtimeI18n: ModulePublicRuntimeConfig['i18n'] ) { - const { strategy, defaultLocale, differentDomains } = nuxtI18nOptions + const { strategy, defaultLocale, differentDomains } = runtimeI18n + const _detectBrowserLanguage = runtimeDetectBrowserLanguage(runtimeI18n) const initialLocale = isFunction(initialLocaleLoader) ? initialLocaleLoader() : initialLocaleLoader __DEBUG__ && console.log('detectLocale: initialLocale -', initialLocale) @@ -257,7 +258,7 @@ export function detectRedirect({ }): string { const nuxtApp = useNuxtApp() const common = initCommonComposableOptions() - const { strategy, differentDomains } = nuxtI18nOptions + const { strategy, differentDomains } = common.runtimeConfig.public.i18n __DEBUG__ && console.log('detectRedirect: targetLocale -> ', targetLocale) __DEBUG__ && console.log('detectRedirect: route -> ', route) __DEBUG__ && console.log('detectRedirect: calledWithRouting -> ', calledWithRouting, routeLocaleGetter(route.to)) @@ -334,8 +335,8 @@ export async function navigate( args: NavigateArgs, { status = 302, enableNavigate = false }: { status?: number; enableNavigate?: boolean } = {} ) { - const { rootRedirect, differentDomains, skipSettingLocaleOnNavigate } = nuxtI18nOptions const { nuxtApp, i18n, locale, route } = args + const { rootRedirect, differentDomains, skipSettingLocaleOnNavigate } = nuxtApp.$config.public.i18n let { redirectPath } = args __DEBUG__ && @@ -408,16 +409,16 @@ export function injectNuxtHelpers(nuxt: NuxtApp, i18n: I18n | VueI18n | Composer } // override prefix for route path, support domain -export function extendPrefixable() { +export function extendPrefixable(runtimeConfig = useRuntimeConfig()) { return (opts: PrefixableOptions): boolean => { - return DefaultPrefixable(opts) && !nuxtI18nOptions.differentDomains + return DefaultPrefixable(opts) && !runtimeConfig.public.i18n.differentDomains } } // override switch locale path intercepter, support domain -export function extendSwitchLocalePathIntercepter(): SwitchLocalePathIntercepter { +export function extendSwitchLocalePathIntercepter(runtimeConfig = useRuntimeConfig()): SwitchLocalePathIntercepter { return (path: string, locale: Locale): string => { - if (nuxtI18nOptions.differentDomains) { + if (runtimeConfig.public.i18n.differentDomains) { const domain = getDomainFromLocale(locale) __DEBUG__ && console.log('extendSwitchLocalePathIntercepter: domain -> ', domain, ' path -> ', path) if (domain) { @@ -434,8 +435,7 @@ export function extendSwitchLocalePathIntercepter(): SwitchLocalePathIntercepter export function extendBaseUrl(): BaseUrlResolveHandler { return (): string => { const ctx = useNuxtApp() - const runtimeConfig = useRuntimeConfig() - const baseUrl = nuxtI18nOptions.baseUrl + const { baseUrl, defaultLocale, differentDomains } = ctx.$config.public.i18n if (isFunction(baseUrl)) { const baseUrlResult = baseUrl(ctx) @@ -443,9 +443,8 @@ export function extendBaseUrl(): BaseUrlResolveHandler { return baseUrlResult } - const localeCodeLoader = nuxtI18nOptions.defaultLocale - const localeCode = isFunction(localeCodeLoader) ? localeCodeLoader() : localeCodeLoader - if (nuxtI18nOptions.differentDomains && localeCode) { + const localeCode = isFunction(defaultLocale) ? defaultLocale() : defaultLocale + if (differentDomains && localeCode) { const domain = getDomainFromLocale(localeCode) if (domain) { __DEBUG__ && console.log('baseUrl: using differentDomains -', domain) @@ -453,13 +452,12 @@ export function extendBaseUrl(): BaseUrlResolveHandler { } } - const config = runtimeConfig?.public?.i18n as { baseUrl?: string } - if (config?.baseUrl) { - __DEBUG__ && console.log('baseUrl: using runtimeConfig -', config.baseUrl) - return config.baseUrl + if (baseUrl) { + __DEBUG__ && console.log('baseUrl: using runtimeConfig -', baseUrl) + return baseUrl } - return baseUrl + return baseUrl! } } diff --git a/src/types.ts b/src/types.ts index 2a33e35f7..35d2a4b91 100644 --- a/src/types.ts +++ b/src/types.ts @@ -127,7 +127,7 @@ export type NuxtI18nOptions< * Do not use in projects */ i18nModules?: { langDir?: string | null; locales?: NuxtI18nOptions['locales'] }[] - rootRedirect?: string | null | RootRedirectOptions + rootRedirect?: string | RootRedirectOptions skipSettingLocaleOnNavigate?: boolean types?: 'composition' | 'legacy' debug?: boolean