Skip to content

Commit 8a807f2

Browse files
committed
fix: handle additional cases
1 parent b8ecccb commit 8a807f2

File tree

2 files changed

+52
-30
lines changed

2 files changed

+52
-30
lines changed

src/runtime/context.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ export function createNuxtI18nContext(nuxt: NuxtApp, vueI18n: I18n, defaultLocal
8181
domainFromLocale(runtimeI18n.domainLocales, useRequestURL({ xForwardedHost: true }), locale)
8282
const baseUrl = createBaseUrlGetter(nuxt, runtimeI18n.baseUrl, defaultLocale, getDomainFromLocale)
8383
const resolvedLocale = useResolvedLocale()
84+
if (import.meta.server && nuxt.ssrContext?.event?.context?.nuxtI18n?.detectLocale) {
85+
resolvedLocale.value = nuxt.ssrContext.event.context.nuxtI18n.detectLocale
86+
}
8487

8588
const ctx: NuxtI18nContext = {
8689
vueI18n,

src/runtime/server/plugin.ts

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { stringify } from 'devalue'
22
import { defineI18nMiddleware } from '@intlify/h3'
3-
import { defineNitroPlugin, useRuntimeConfig, useStorage } from 'nitropack/runtime'
3+
import { defineNitroPlugin, useStorage } from 'nitropack/runtime'
44
import { tryUseI18nContext, createI18nContext } from './context'
55
import { createUserLocaleDetector } from './utils/locale-detector'
66
import { pickNested } from './utils/messages-utils'
@@ -31,11 +31,9 @@ export function prefixable(currentLocale: string, defaultLocale: string): boolea
3131
}
3232

3333
export default defineNitroPlugin(async nitro => {
34-
const runtimeConfig = useRuntimeConfig()
35-
3634
const runtimeI18n = useRuntimeI18n()
3735
const rootRedirect = resolveRootRedirect(runtimeI18n.rootRedirect)
38-
const defaultLocale: string = runtimeI18n.defaultLocale || ''
36+
const _defaultLocale: string = runtimeI18n.defaultLocale || ''
3937

4038
// clear cache for i18n handlers on startup
4139
const cacheStorage = useStorage('cache')
@@ -88,12 +86,22 @@ export default defineNitroPlugin(async nitro => {
8886
}
8987
const baseUrlGetter = createBaseUrlGetter()
9088

89+
async function doRedirect(event: H3Event, to: string, code: number) {
90+
// console.log(`[nuxt-i18n] Redirecting to ${to} with code ${code}`)
91+
await sendRedirect(event, to, code)
92+
}
93+
94+
function doSetCookie(event: H3Event, name: string, value: string, options?: Record<string, any>) {
95+
// console.log(`[nuxt-i18n] Setting cookie ${name} to ${value}`)
96+
setCookie(event, name, value, { path: '/', maxAge: 60 * 60 * 24 * 365, sameSite: 'lax', ...options })
97+
}
98+
9199
nitro.hooks.hook('request', async (event: H3Event) => {
92100
if (event.path === '/.well-known/appspecific/com.chrome.devtools.json' || event.path === '/favicon.ico') {
93101
sendNoContent(event)
94102
return
95103
}
96-
const options = await setupVueI18nOptions(getDefaultLocaleForDomain(getHost(event)) || defaultLocale)
104+
const options = await setupVueI18nOptions(getDefaultLocaleForDomain(getHost(event)) || _defaultLocale)
97105
const localeConfigs = createLocaleConfigs(options.fallbackLocale)
98106
const detector = useDetectors(event, detectConfig)
99107

@@ -103,6 +111,9 @@ export default defineNitroPlugin(async nitro => {
103111
if (detectConfig.enabled) {
104112
for (const detected of detect(detector, event.path)) {
105113
if (detected.locale && isSupportedLocale(detected.locale)) {
114+
// console.log(
115+
// `[nuxt-i18n] Detected locale "${detected.locale}" from ${detected.source} for path "${event.path}"`
116+
// )
106117
locale = detected.locale
107118
break
108119
}
@@ -114,50 +125,58 @@ export default defineNitroPlugin(async nitro => {
114125
const skipRedirectOnRoot = detectConfig.redirectOn === 'root' && event.path !== '/'
115126

116127
if (rootRedirect && event.path === '/') {
117-
const domainForLocale = getDomainFromLocale(event, locale)
118-
const defaultLocale =
119-
(__MULTI_DOMAIN_LOCALES__ && domainForLocale && getDefaultLocaleForDomain(getHost(event))) ||
120-
runtimeI18n.defaultLocale
121-
122128
const rootRedirectIsLocalized = isSupportedLocale(detector.route(rootRedirect.path))
123129
const resolvedPath = rootRedirectIsLocalized
124130
? rootRedirect.path
125131
: matchLocalized(
126132
rootRedirect.path,
127-
detectConfig.enabled ? locale || defaultLocale : defaultLocale,
128-
defaultLocale
133+
(detectConfig.enabled && locale) || options.defaultLocale,
134+
options.defaultLocale
129135
)
130136
if (resolvedPath) {
131-
setCookie(event, 'i18n_redirected', locale, { path: '/', maxAge: 60 * 60 * 24 * 365, sameSite: 'lax' })
132-
const fullDestination = withoutTrailingSlash(joinURL(baseUrlGetter(event, defaultLocale), resolvedPath))
133-
await sendRedirect(event, fullDestination, rootRedirect.code || 302)
137+
const _locale = detectConfig.enabled ? locale || options.defaultLocale : options.defaultLocale
138+
doSetCookie(event, 'i18n_redirected', _locale, { path: '/', maxAge: 60 * 60 * 24 * 365, sameSite: 'lax' })
139+
event.context.nuxtI18n.detectLocale = _locale
140+
await doRedirect(
141+
event,
142+
withoutTrailingSlash(joinURL(baseUrlGetter(event, options.defaultLocale), resolvedPath)),
143+
rootRedirect.code || 302
144+
)
134145
return
135146
}
136147
}
137148

138-
if (locale && detectConfig.enabled && !skipRedirectOnPrefix && !skipRedirectOnRoot) {
149+
// path locale exists and we skip redirect on prefix or root
150+
// ensure cookie is set to avoid redirecting from nuxt context
151+
if (skipRedirectOnPrefix && pathLocale && isSupportedLocale(pathLocale)) {
152+
doSetCookie(event, 'i18n_redirected', pathLocale)
153+
event.context.nuxtI18n.detectLocale = pathLocale
154+
locale = pathLocale
155+
} else if (locale && detectConfig.enabled && !skipRedirectOnPrefix && !skipRedirectOnRoot) {
139156
event.context.nuxtI18n.detectRoute = event.path
140157

141-
const domainForLocale = getDomainFromLocale(event, locale)
142-
const defaultLocale =
143-
(__MULTI_DOMAIN_LOCALES__ && domainForLocale && getDefaultLocaleForDomain(getHost(event))) ||
144-
runtimeI18n.defaultLocale
145-
const localeInPath = detector.route(event.path)
146-
const entry = isSupportedLocale(localeInPath) ? event.path.slice(localeInPath!.length + 1) : event.path
147-
const resolvedPath = matchLocalized(entry || '/', locale, defaultLocale)
158+
const entry = isSupportedLocale(pathLocale) ? event.path.slice(pathLocale!.length + 1) : event.path
159+
const resolvedPath = matchLocalized(entry || '/', locale, options.defaultLocale)
148160
if (resolvedPath && resolvedPath !== event.path) {
149-
setCookie(event, 'i18n_redirected', locale, { path: '/', maxAge: 60 * 60 * 24 * 365, sameSite: 'lax' })
150-
const fullDestination = withoutTrailingSlash(joinURL(baseUrlGetter(event, defaultLocale), resolvedPath))
151-
await sendRedirect(event, fullDestination, 302)
161+
event.context.nuxtI18n.detectLocale = locale
162+
doSetCookie(event, 'i18n_redirected', locale, { path: '/', maxAge: 60 * 60 * 24 * 365, sameSite: 'lax' })
163+
await doRedirect(
164+
event,
165+
withoutTrailingSlash(joinURL(baseUrlGetter(event, options.defaultLocale), resolvedPath)),
166+
302
167+
)
152168
return
153169
}
154170
}
155171

156172
if (!pathLocale && __I18N_STRATEGY__ === 'prefix') {
157-
const resolvedPath = matchLocalized(event.path, defaultLocale, defaultLocale)
173+
const resolvedPath = matchLocalized(event.path, options.defaultLocale, options.defaultLocale)
158174
if (resolvedPath && resolvedPath !== event.path) {
159-
const fullDestination = withoutTrailingSlash(joinURL(baseUrlGetter(event, defaultLocale), resolvedPath))
160-
sendRedirect(event, fullDestination, 302)
175+
await doRedirect(
176+
event,
177+
withoutTrailingSlash(joinURL(baseUrlGetter(event, options.defaultLocale), resolvedPath)),
178+
302
179+
)
161180

162181
return
163182
}
@@ -207,7 +226,7 @@ export default defineNitroPlugin(async nitro => {
207226

208227
// enable server-side translations and user locale-detector
209228
if (localeDetector != null) {
210-
const options = await setupVueI18nOptions(defaultLocale)
229+
const options = await setupVueI18nOptions(_defaultLocale)
211230
const i18nMiddleware = defineI18nMiddleware({
212231
...(options as CoreOptions),
213232
locale: createUserLocaleDetector(options.locale, options.fallbackLocale)

0 commit comments

Comments
 (0)