Skip to content

Commit

Permalink
refactor: pass generated options through runtimeConfig (#2828)
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede authored Mar 7, 2024
1 parent bf63a09 commit b001647
Show file tree
Hide file tree
Showing 13 changed files with 117 additions and 96 deletions.
4 changes: 1 addition & 3 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion src/gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const generateVueI18nConfiguration = (config: Required<VueI18nConfigPathInfo>, 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 =
Expand Down
32 changes: 30 additions & 2 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -140,8 +140,20 @@ export default defineNuxtModule<NuxtI18nOptions>({
*/

// 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') {
Expand Down Expand Up @@ -223,6 +235,9 @@ export default defineNuxtModule<NuxtI18nOptions>({
})
}

// @ts-expect-error type error
nuxt.options.runtimeConfig.public.i18n.configLocales = simplifyLocaleOptions(nuxt, defu({}, options))

addTemplate({
filename: NUXT_I18N_TEMPLATE_OPTIONS_KEY,
write: true,
Expand Down Expand Up @@ -337,7 +352,20 @@ export default defineNuxtModule<NuxtI18nOptions>({
export interface ModuleOptions extends NuxtI18nOptions {}

export interface ModulePublicRuntimeConfig {
i18n: Required<Pick<NuxtI18nOptions<unknown>, 'baseUrl' | 'detectBrowserLanguage'>>
i18n: Pick<NuxtI18nOptions<unknown>, 'baseUrl' | 'rootRedirect'> &
Pick<
Required<NuxtI18nOptions<unknown>>,
| 'differentDomains'
| 'skipSettingLocaleOnNavigate'
| 'defaultLocale'
| 'lazy'
| 'defaultDirection'
| 'detectBrowserLanguage'
| 'strategy'
| 'routesNameSeparator'
| 'defaultLocaleRouteNameSuffix'
| 'trailingSlash'
> & { configLocales: NonNullable<Required<NuxtI18nOptions<unknown>>['locales']> }
}

export interface ModuleHooks {
Expand Down
2 changes: 0 additions & 2 deletions src/options.d.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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'
2 changes: 1 addition & 1 deletion src/runtime/composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export type RouteBaseNameFunction = (givenRoute?: RouteLocationNormalizedLoaded)
* @public
*/
export function useRouteBaseName(): RouteBaseNameFunction {
return getRouteBaseName
return wrapComposable(getRouteBaseName)
}

/**
Expand Down
26 changes: 13 additions & 13 deletions src/runtime/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,15 @@ 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'

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
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down
43 changes: 21 additions & 22 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { defineNuxtPlugin, useRoute, addRouteMiddleware, defineNuxtRouteMiddlewa
import {
localeCodes,
vueI18nConfigs,
nuxtI18nOptions as _nuxtI18nOptions,
isSSG,
localeLoaders,
parallelPlugin,
Expand Down Expand Up @@ -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 || {}
Expand All @@ -75,23 +75,23 @@ 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)

// load initial vue-i18n locale messages
vueI18nOptions.messages = await loadInitialMessages(vueI18nOptions.messages, localeLoaders, {
localeCodes,
initialLocale,
lazy: nuxtI18nOptions.lazy,
defaultLocale: nuxtI18nOptions.defaultLocale,
lazy: runtimeI18n.lazy,
defaultLocale: runtimeI18n.defaultLocale,
fallbackLocale: vueI18nOptions.fallbackLocale
})

Expand All @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -194,8 +193,8 @@ export default defineNuxtPlugin({
const setter = (locale: Locale, message: Record<string, any>) => 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)
Expand Down Expand Up @@ -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
Expand All @@ -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
})
)
Expand Down
9 changes: 4 additions & 5 deletions src/runtime/routing/compatibles/head.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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<I18nHeadMetaInfo> = {
Expand Down Expand Up @@ -83,7 +82,7 @@ export function getHreflangLinks(
idAttribute: NonNullable<I18nHeadOptions['identifierAttribute']>
) {
const baseUrl = getBaseUrl()
const { defaultLocale, strategy } = nuxtI18nOptions
const { defaultLocale, strategy } = useRuntimeConfig().public.i18n
const links: MetaAttrs[] = []

if (strategy === 'no_prefix') return links
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit b001647

Please sign in to comment.