Skip to content

Commit

Permalink
refactor: separate multiDomainLocales logic (#3108)
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede authored Sep 18, 2024
1 parent b2d4916 commit d63328c
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 45 deletions.
75 changes: 72 additions & 3 deletions src/runtime/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@
import { isArray, isString, isObject } from '@intlify/shared'
import { hasProtocol } from 'ufo'
import isHTTPS from 'is-https'
import { useRequestHeaders, useRequestEvent, useCookie as useNuxtCookie, useRuntimeConfig, useNuxtApp } from '#imports'
import {
useRequestHeaders,
useRequestEvent,
useCookie as useNuxtCookie,
useRuntimeConfig,
useNuxtApp,
useRouter
} from '#imports'
import { NUXT_I18N_MODULE_ID, DEFAULT_COOKIE_KEY, isSSG, localeCodes, normalizedLocales } from '#build/i18n.options.mjs'
import { findBrowserLocale, getLocalesRegex } from './routing/utils'
import { findBrowserLocale, getLocalesRegex, getRouteName } from './routing/utils'
import { initCommonComposableOptions, type CommonComposableOptions } from './utils'
import { createLogger } from 'virtual:nuxt-i18n-logger'

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 { CookieRef, NuxtApp } from 'nuxt/app'
import type { ModulePublicRuntimeConfig } from '../module'

export function formatMessage(message: string) {
Expand Down Expand Up @@ -374,4 +381,66 @@ export const runtimeDetectBrowserLanguage = (
return opts?.detectBrowserLanguage
}

/**
* Removes default routes depending on domain
*/
export function setupMultiDomainLocales(nuxtContext: NuxtApp, defaultLocaleDomain: string) {
const { multiDomainLocales, strategy, routesNameSeparator, defaultLocaleRouteNameSuffix } =
nuxtContext.$config.public.i18n

// feature disabled
if (!multiDomainLocales) return

// incompatible strategy
if (!(strategy === 'prefix_except_default' || strategy === 'prefix_and_default')) return

const router = useRouter()
const defaultRouteSuffix = [routesNameSeparator, defaultLocaleRouteNameSuffix].join('')

// remove or rename default routes if not applicable for domain
for (const route of router.getRoutes()) {
const routeName = getRouteName(route.name)

if (!routeName.includes(defaultRouteSuffix)) continue

const routeNameLocale = routeName.split(routesNameSeparator)[1]
if (routeNameLocale === defaultLocaleDomain) {
route.name = routeName.replace(defaultRouteSuffix, '')
continue
}

// use `route.name` directly as `routeName` stringifies `Symbol`
// @ts-expect-error type mismatch
router.removeRoute(route.name)
}
}

/**
* Returns default locale for the current domain, returns `defaultLocale` by default
*/
export function getDefaultLocaleForDomain(nuxtContext: NuxtApp) {
const { locales, defaultLocale, multiDomainLocales } = nuxtContext.$config.public.i18n

let defaultLocaleDomain: string = defaultLocale || ''

if (!multiDomainLocales) {
return defaultLocaleDomain
}

const host = getHost()
const hasDefaultForDomains = locales.some(
(l): l is LocaleObject => typeof l !== 'string' && Array.isArray(l.defaultForDomains)
)

if (hasDefaultForDomains) {
const findDefaultLocale = locales.find((l): l is LocaleObject =>
typeof l === 'string' || !Array.isArray(l.defaultForDomains) ? false : l.defaultForDomains.includes(host ?? '')
)

defaultLocaleDomain = findDefaultLocale?.code ?? ''
}

return defaultLocaleDomain
}

/* eslint-enable @typescript-eslint/no-explicit-any */
47 changes: 5 additions & 42 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { computed, ref, watch } from 'vue'
import { createI18n } from 'vue-i18n'
import {
defineNuxtPlugin,
useRoute,
addRouteMiddleware,
defineNuxtRouteMiddleware,
useNuxtApp,
useRouter
} from '#imports'
import { defineNuxtPlugin, useRoute, addRouteMiddleware, defineNuxtRouteMiddleware, useNuxtApp } from '#imports'
import {
localeCodes,
vueI18nConfigs,
Expand All @@ -26,7 +19,8 @@ import {
detectBrowserLanguage,
getI18nCookie,
runtimeDetectBrowserLanguage,
getHost
getDefaultLocaleForDomain,
setupMultiDomainLocales
} from '../internal'
import { inBrowser, resolveBaseUrl } from '../routing/utils'
import { extendI18n, createLocaleFromRouteGetter } from '../routing/extends'
Expand Down Expand Up @@ -58,40 +52,9 @@ export default defineNuxtPlugin<NuxtI18nPluginInjections>({
const route = useRoute()
const { vueApp: app } = nuxt
const nuxtContext = nuxt as unknown as NuxtApp
const host = getHost()
const { locales, defaultLocale, multiDomainLocales, strategy } = nuxtContext.$config.public.i18n

const hasDefaultForDomains = locales.some(
(l): l is LocaleObject => typeof l !== 'string' && Array.isArray(l.defaultForDomains)
)

let defaultLocaleDomain: string
if (defaultLocale) {
defaultLocaleDomain = defaultLocale
} else if (hasDefaultForDomains) {
const findDefaultLocale = locales.find((l): l is LocaleObject =>
typeof l === 'string' || !Array.isArray(l.defaultForDomains) ? false : l.defaultForDomains.includes(host ?? '')
)

defaultLocaleDomain = findDefaultLocale?.code ?? ''
} else {
defaultLocaleDomain = ''
}

if (multiDomainLocales && (strategy === 'prefix_except_default' || strategy === 'prefix_and_default')) {
const router = useRouter()
router.getRoutes().forEach(route => {
if (route.name?.toString().includes('___default')) {
const routeNameLocale = route.name.toString().split('___')[1]
if (routeNameLocale !== defaultLocaleDomain) {
router.removeRoute(route.name)
} else {
const newRouteName = route.name.toString().replace('___default', '')
route.name = newRouteName
}
}
})
}
const defaultLocaleDomain = getDefaultLocaleForDomain(nuxtContext)
setupMultiDomainLocales(nuxtContext, defaultLocaleDomain)

// Fresh copy per request to prevent reusing mutated options
const runtimeI18n = { ...nuxtContext.$config.public.i18n, defaultLocale: defaultLocaleDomain }
Expand Down

0 comments on commit d63328c

Please sign in to comment.