Skip to content

Commit f0fa7d0

Browse files
authoredOct 1, 2024··
fix: handle middleware redirects to default locale and same path (#2636)
* test: add test case for middleware redirect to same path just changing locale to defalt * fix: don't use request locale as fallback locale for redirects
1 parent be952a7 commit f0fa7d0

File tree

4 files changed

+38
-13
lines changed

4 files changed

+38
-13
lines changed
 

‎edge-runtime/lib/response.ts

+9-12
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ interface BuildResponseOptions {
2424
request: Request
2525
result: FetchEventResult
2626
nextConfig?: RequestData['nextConfig']
27-
requestLocale?: string
2827
}
2928

3029
export const buildResponse = async ({
@@ -33,7 +32,6 @@ export const buildResponse = async ({
3332
request,
3433
result,
3534
nextConfig,
36-
requestLocale,
3735
}: BuildResponseOptions): Promise<Response | void> => {
3836
logger
3937
.withFields({ is_nextresponse_next: result.response.headers.has('x-middleware-next') })
@@ -197,11 +195,10 @@ export const buildResponse = async ({
197195
return addMiddlewareHeaders(context.rewrite(target), res)
198196
}
199197

200-
// If we are redirecting a request that had a locale in the URL, we need to add it back in
201-
if (redirect && requestLocale) {
202-
redirect = normalizeLocalizedTarget({ target: redirect, request, nextConfig, requestLocale })
198+
if (redirect) {
199+
redirect = normalizeLocalizedTarget({ target: redirect, request, nextConfig })
203200
if (redirect === request.url) {
204-
logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url')
201+
logger.withFields({ redirect_url: redirect }).debug('Redirect url is same as original url')
205202
return
206203
}
207204
res.headers.set('location', redirect)
@@ -234,25 +231,25 @@ function normalizeLocalizedTarget({
234231
target,
235232
request,
236233
nextConfig,
237-
requestLocale,
238234
}: {
239235
target: string
240236
request: Request
241237
nextConfig?: RequestData['nextConfig']
242-
requestLocale?: string
243-
}) {
238+
}): string {
244239
const targetUrl = new URL(target, request.url)
245240

246241
const normalizedTarget = normalizeLocalePath(targetUrl.pathname, nextConfig?.i18n?.locales)
247242

248-
const locale = normalizedTarget.detectedLocale ?? requestLocale
249243
if (
250-
locale &&
244+
normalizedTarget.detectedLocale &&
251245
!normalizedTarget.pathname.startsWith(`/api/`) &&
252246
!normalizedTarget.pathname.startsWith(`/_next/static/`)
253247
) {
254248
targetUrl.pathname =
255-
addBasePath(`/${locale}${normalizedTarget.pathname}`, nextConfig?.basePath) || `/`
249+
addBasePath(
250+
`/${normalizedTarget.detectedLocale}${normalizedTarget.pathname}`,
251+
nextConfig?.basePath,
252+
) || `/`
256253
} else {
257254
targetUrl.pathname = addBasePath(normalizedTarget.pathname, nextConfig?.basePath) || `/`
258255
}

‎edge-runtime/middleware.ts

-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export async function handleMiddleware(
6161
logger: reqLogger,
6262
request,
6363
result,
64-
requestLocale: nextRequest.detectedLocale,
6564
nextConfig,
6665
})
6766

‎tests/fixtures/middleware-i18n/middleware.js

+5
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ export async function middleware(request) {
8181
return Response.redirect(new URL('/new-home#fragment', url))
8282
}
8383

84+
if (url.locale !== 'en' && url.pathname === '/redirect-to-same-page-but-default-locale') {
85+
url.locale = 'en'
86+
return Response.redirect(url)
87+
}
88+
8489
if (url.pathname.includes('/json')) {
8590
return NextResponse.json({
8691
requestUrlPathname: new URL(request.url).pathname,

‎tests/integration/edge-handler.test.ts

+24
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,30 @@ describe('page router', () => {
503503
expect(response.status).toBe(302)
504504
})
505505

506+
test<FixtureTestContext>('should support redirects to default locale without changing path', async (ctx) => {
507+
await createFixture('middleware-i18n', ctx)
508+
await runPlugin(ctx)
509+
const origin = await LocalServer.run(async (req, res) => {
510+
res.write(
511+
JSON.stringify({
512+
url: req.url,
513+
headers: req.headers,
514+
}),
515+
)
516+
res.end()
517+
})
518+
ctx.cleanup?.push(() => origin.stop())
519+
const response = await invokeEdgeFunction(ctx, {
520+
functions: ['___netlify-edge-handler-middleware'],
521+
origin,
522+
url: `/fr/redirect-to-same-page-but-default-locale`,
523+
redirect: 'manual',
524+
})
525+
const url = new URL(response.headers.get('location') ?? '', 'http://n/')
526+
expect(url.pathname).toBe('/redirect-to-same-page-but-default-locale')
527+
expect(response.status).toBe(302)
528+
})
529+
506530
test<FixtureTestContext>('should preserve locale in request.nextUrl', async (ctx) => {
507531
await createFixture('middleware-i18n', ctx)
508532
await runPlugin(ctx)

0 commit comments

Comments
 (0)
Please sign in to comment.