From 7a1f24fcb1887ddea652efffe72925da9a0f96d2 Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Thu, 14 Sep 2023 09:21:44 +0200 Subject: [PATCH] fix(RSC): Always read header in RSC render --- .../next-intl/src/middleware/middleware.tsx | 17 +++-------------- .../src/server/getLocaleFromHeader.tsx | 13 +++---------- .../test/middleware/middleware.test.tsx | 10 ++++++++++ 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/packages/next-intl/src/middleware/middleware.tsx b/packages/next-intl/src/middleware/middleware.tsx index 236e768a6..455f5069a 100644 --- a/packages/next-intl/src/middleware/middleware.tsx +++ b/packages/next-intl/src/middleware/middleware.tsx @@ -119,20 +119,9 @@ export default function createMiddleware( const hasUnknownHost = configWithDefaults.domains != null && !domain; function getResponseInit() { - const responseInit = { - request: { - headers: request.headers - } - }; - - if (hasOutdatedCookie) { - responseInit.request.headers = new Headers( - responseInit.request.headers - ); - responseInit.request.headers.set(HEADER_LOCALE_NAME, locale); - } - - return responseInit; + const headers = new Headers(request.headers); + headers.set(HEADER_LOCALE_NAME, locale); + return {request: {headers}}; } function rewrite(url: string) { diff --git a/packages/next-intl/src/server/getLocaleFromHeader.tsx b/packages/next-intl/src/server/getLocaleFromHeader.tsx index a9ed6988c..1b0e919a0 100644 --- a/packages/next-intl/src/server/getLocaleFromHeader.tsx +++ b/packages/next-intl/src/server/getLocaleFromHeader.tsx @@ -1,19 +1,12 @@ -import {cookies, headers} from 'next/headers'; +import {headers} from 'next/headers'; import {cache} from 'react'; -import {COOKIE_LOCALE_NAME, HEADER_LOCALE_NAME} from '../shared/constants'; +import {HEADER_LOCALE_NAME} from '../shared/constants'; const getLocaleFromHeader = cache(() => { let locale; try { - // A header is only set when we're changing the locale, - // otherwise we reuse an existing one from the cookie. - const requestHeaders = headers(); - if (requestHeaders.has(HEADER_LOCALE_NAME)) { - locale = requestHeaders.get(HEADER_LOCALE_NAME); - } else { - locale = cookies().get(COOKIE_LOCALE_NAME)?.value; - } + locale = headers().get(HEADER_LOCALE_NAME); } catch (error) { if ( process.env.NODE_ENV !== 'production' && diff --git a/packages/next-intl/test/middleware/middleware.test.tsx b/packages/next-intl/test/middleware/middleware.test.tsx index 8e2f585fb..0b3a75447 100644 --- a/packages/next-intl/test/middleware/middleware.test.tsx +++ b/packages/next-intl/test/middleware/middleware.test.tsx @@ -219,6 +219,16 @@ describe('prefix-based routing', () => { ); }); + it('always provides the locale via a request header, even if a cookie exists with the correct value (see https://github.com/amannn/next-intl/discussions/446)', () => { + middleware(createMockRequest('/', 'en', 'http://localhost:3000', 'en')); + expect(MockedNextResponse.rewrite).toHaveBeenCalled(); + expect( + MockedNextResponse.rewrite.mock.calls[0][1]?.request?.headers?.get( + 'x-next-intl-locale' + ) + ).toBe('en'); + }); + describe('localized pathnames', () => { const middlewareWithPathnames = createIntlMiddleware({ defaultLocale: 'en',