From 5d7c353a7bcd9c474474df9c72d2cb43273fd3a9 Mon Sep 17 00:00:00 2001 From: pieh Date: Tue, 1 Oct 2024 09:19:32 +0200 Subject: [PATCH 1/2] test: add test case for middleware redirect to same path just changing locale to defalt --- tests/fixtures/middleware-i18n/middleware.js | 5 ++++ tests/integration/edge-handler.test.ts | 24 ++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/tests/fixtures/middleware-i18n/middleware.js b/tests/fixtures/middleware-i18n/middleware.js index 24517d72de..0057764f47 100644 --- a/tests/fixtures/middleware-i18n/middleware.js +++ b/tests/fixtures/middleware-i18n/middleware.js @@ -81,6 +81,11 @@ export async function middleware(request) { return Response.redirect(new URL('/new-home#fragment', url)) } + if (url.locale !== 'en' && url.pathname === '/redirect-to-same-page-but-default-locale') { + url.locale = 'en' + return Response.redirect(url) + } + if (url.pathname.includes('/json')) { return NextResponse.json({ requestUrlPathname: new URL(request.url).pathname, diff --git a/tests/integration/edge-handler.test.ts b/tests/integration/edge-handler.test.ts index 78949d2d6c..f938a1dc12 100644 --- a/tests/integration/edge-handler.test.ts +++ b/tests/integration/edge-handler.test.ts @@ -503,6 +503,30 @@ describe('page router', () => { expect(response.status).toBe(302) }) + test('should support redirects to default locale without changing path', async (ctx) => { + await createFixture('middleware-i18n', ctx) + await runPlugin(ctx) + const origin = await LocalServer.run(async (req, res) => { + res.write( + JSON.stringify({ + url: req.url, + headers: req.headers, + }), + ) + res.end() + }) + ctx.cleanup?.push(() => origin.stop()) + const response = await invokeEdgeFunction(ctx, { + functions: ['___netlify-edge-handler-middleware'], + origin, + url: `/fr/redirect-to-same-page-but-default-locale`, + redirect: 'manual', + }) + const url = new URL(response.headers.get('location') ?? '', 'http://n/') + expect(url.pathname).toBe('/redirect-to-same-page-but-default-locale') + expect(response.status).toBe(302) + }) + test('should preserve locale in request.nextUrl', async (ctx) => { await createFixture('middleware-i18n', ctx) await runPlugin(ctx) From f9e7f3ac419f43bcbb07621e1991708167abb607 Mon Sep 17 00:00:00 2001 From: pieh Date: Tue, 1 Oct 2024 10:08:29 +0200 Subject: [PATCH 2/2] fix: don't use request locale as fallback locale for redirects --- edge-runtime/lib/response.ts | 21 +++++++++------------ edge-runtime/middleware.ts | 1 - 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/edge-runtime/lib/response.ts b/edge-runtime/lib/response.ts index 6e2366354b..3fd82c5ab0 100644 --- a/edge-runtime/lib/response.ts +++ b/edge-runtime/lib/response.ts @@ -24,7 +24,6 @@ interface BuildResponseOptions { request: Request result: FetchEventResult nextConfig?: RequestData['nextConfig'] - requestLocale?: string } export const buildResponse = async ({ @@ -33,7 +32,6 @@ export const buildResponse = async ({ request, result, nextConfig, - requestLocale, }: BuildResponseOptions): Promise => { logger .withFields({ is_nextresponse_next: result.response.headers.has('x-middleware-next') }) @@ -197,11 +195,10 @@ export const buildResponse = async ({ return addMiddlewareHeaders(context.rewrite(target), res) } - // If we are redirecting a request that had a locale in the URL, we need to add it back in - if (redirect && requestLocale) { - redirect = normalizeLocalizedTarget({ target: redirect, request, nextConfig, requestLocale }) + if (redirect) { + redirect = normalizeLocalizedTarget({ target: redirect, request, nextConfig }) if (redirect === request.url) { - logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url') + logger.withFields({ redirect_url: redirect }).debug('Redirect url is same as original url') return } res.headers.set('location', redirect) @@ -234,25 +231,25 @@ function normalizeLocalizedTarget({ target, request, nextConfig, - requestLocale, }: { target: string request: Request nextConfig?: RequestData['nextConfig'] - requestLocale?: string -}) { +}): string { const targetUrl = new URL(target, request.url) const normalizedTarget = normalizeLocalePath(targetUrl.pathname, nextConfig?.i18n?.locales) - const locale = normalizedTarget.detectedLocale ?? requestLocale if ( - locale && + normalizedTarget.detectedLocale && !normalizedTarget.pathname.startsWith(`/api/`) && !normalizedTarget.pathname.startsWith(`/_next/static/`) ) { targetUrl.pathname = - addBasePath(`/${locale}${normalizedTarget.pathname}`, nextConfig?.basePath) || `/` + addBasePath( + `/${normalizedTarget.detectedLocale}${normalizedTarget.pathname}`, + nextConfig?.basePath, + ) || `/` } else { targetUrl.pathname = addBasePath(normalizedTarget.pathname, nextConfig?.basePath) || `/` } diff --git a/edge-runtime/middleware.ts b/edge-runtime/middleware.ts index 73a37a6007..8a9452f649 100644 --- a/edge-runtime/middleware.ts +++ b/edge-runtime/middleware.ts @@ -61,7 +61,6 @@ export async function handleMiddleware( logger: reqLogger, request, result, - requestLocale: nextRequest.detectedLocale, nextConfig, })