Skip to content

Commit

Permalink
refactor: options passing
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede committed Jan 21, 2024
1 parent 9e213d0 commit 94c6cae
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 291 deletions.
6 changes: 2 additions & 4 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { applyLayerOptions, checkLayerOptions, resolveLayerVueI18nConfigInfo } f
import { generateTemplateNuxtI18nOptions } from './template'

import type { HookResult } from '@nuxt/schema'
import type { NuxtI18nOptions, SimpleLocaleObject } from './types'
import type { NuxtI18nOptions } from './types'

export * from './types'

Expand Down Expand Up @@ -213,10 +213,8 @@ export default defineNuxtModule<NuxtI18nOptions>({
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
Expand Down
5 changes: 2 additions & 3 deletions src/options.d.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -25,7 +25,7 @@ export const vueI18nConfigs: VueI18nConfig[]
export const localeCodes: string[] = []
export const nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>> = {}
export const nuxtI18nOptionsDefault: NuxtI18nOptionsDefault = {}
export const nuxtI18nInternalOptions: DeepRequired<NuxtI18nInternalOptions> = {}
export const normalizedLocales: LocaleObject[] = []
export const NUXT_I18N_MODULE_ID = ''
export const isSSG = false
export const parallelPlugin: boolean
Expand All @@ -43,7 +43,6 @@ export const DEFAULT_DYNAMIC_PARAMS_KEY: typeof constants.DEFAULT_DYNAMIC_PARAMS
export {
NuxtI18nOptions,
NuxtI18nOptionsDefault,
NuxtI18nInternalOptions,
DetectBrowserLanguageOptions,
RootRedirectOptions
} from './types'
48 changes: 18 additions & 30 deletions src/runtime/composables/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
import { useRoute, useRequestHeaders, useCookie, useRouter } from '#imports'
import { useRoute, useRouter, useRequestHeaders, useCookie as useNuxtCookie } 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 } 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'

import { getNormalizedLocales, type HeadParam } from '../utils'
import { getNormalizedLocales } from '../utils'
import {
getAlternateOgLocales,
getCanonicalLink,
Expand All @@ -32,8 +20,14 @@ import {
} from '../routing/compatibles'
import { findBrowserLocale, getLocale, getLocales } from '../routing/utils'

import type { Ref } from 'vue'
import type { Locale } from 'vue-i18n'
import type { RouteLocation, RouteLocationNormalizedLoaded, RouteLocationRaw, Router } from 'vue-router'
import type { I18nHeadMetaInfo, I18nHeadOptions, SeoAttributesOptions } from '#build/i18n.options.mjs'
import type { HeadParam } from '../utils'

export * from 'vue-i18n'
export * from './shared'

/**
* Returns a function to set i18n params.
Expand Down Expand Up @@ -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(
Expand All @@ -350,30 +344,24 @@ export function useBrowserLocale(normalizedLocales = nuxtI18nInternalOptions.__n
*
* @public
*/
export function useCookieLocale(
options: Required<Pick<DetectBrowserLanguageOptions, 'useCookie' | 'cookieKey'>> & {
localeCodes: readonly string[]
} = {
useCookie: nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
cookieKey: nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
localeCodes: _localeCodes
}
): Ref<string> {
export function useCookieLocale(): Ref<string> {
// Support for importing from `#imports` is generated by auto `imports` nuxt module, so `ref` is imported from `vue`
const locale: Ref<string> = 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<string>(options.cookieKey) as Ref<string>
code = cookie.value
code = useNuxtCookie<string>(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
}
}
Expand Down
82 changes: 36 additions & 46 deletions src/runtime/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -81,42 +82,43 @@ 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<NuxtI18nInternalOptions>): 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) {
const header = useRequestHeaders(['accept-language'])
__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)
}
}

return ret
}

export function getLocaleCookie({
useCookie = nuxtI18nOptionsDefault.detectBrowserLanguage.useCookie,
cookieKey = nuxtI18nOptionsDefault.detectBrowserLanguage.cookieKey,
localeCodes = []
}: Pick<DetectBrowserLanguageOptions, 'useCookie' | 'cookieKey'> & {
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)

Expand All @@ -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
}
Expand Down Expand Up @@ -187,13 +180,10 @@ export const DefaultDetectBrowserLanguageFromResult: DetectBrowserLanguageFromRe
from: 'unknown'
}

export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(
export function detectBrowserLanguage(
route: string | RouteLocationNormalized | RouteLocationNormalizedLoaded,
nuxtI18nOptions: DeepRequired<NuxtI18nOptions<Context>>,
nuxtI18nInternalOptions: DeepRequired<NuxtI18nInternalOptions>,
vueI18nOptions: I18nOptions,
vueI18nOptionsLocale: Locale | undefined,
detectLocaleContext: DetectLocaleContext,
localeCodes: string[] = [],
locale: Locale = ''
): DetectBrowserLanguageFromResult {
const { strategy } = nuxtI18nOptions
Expand Down Expand Up @@ -244,13 +234,13 @@ export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(

// 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)
}
Expand All @@ -275,7 +265,7 @@ export function detectBrowserLanguage<Context extends NuxtApp = NuxtApp>(
localeFrom
)

const vueI18nLocale = locale || vueI18nOptions.locale
const vueI18nLocale = locale || vueI18nOptionsLocale
__DEBUG__ && console.log('detectBrowserLanguage: vueI18nLocale', vueI18nLocale)

// handle cookie option to prevent multiple redirects
Expand Down Expand Up @@ -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<Locale, { domain?: string }> }
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) {
Expand Down
Loading

0 comments on commit 94c6cae

Please sign in to comment.