Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: pass generated options through runtimeConfig #2828

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm πŸ€”
I would also prefer locales instead of configLocales if possible.
It seems that locales have been introduced by this PR.
#2446

In v9, we should also be organized runtimeConfig.
locales should be domainLocales and configLocales should be locales.

@BobbieGoede
What do you think?

Copy link
Collaborator Author

@BobbieGoede BobbieGoede Mar 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In v9, we should also be organized runtimeConfig.
locales should be domainLocales and configLocales should be locales.

Agreed, that sounds good! I have added a reference in the roadmap discussion #2814

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Okay, I'll merge this PR!

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