Skip to content

Commit 1a5e0ec

Browse files
authored
fix: Don't attach alternate links for redirects and consider port of a domain that is being redirected to (#1729)
1 parent 22cf1cd commit 1a5e0ec

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

packages/next-intl/.size-limit.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ const config: SizeLimitConfig = [
4242
{
4343
name: "import * from 'next-intl/middleware'",
4444
path: 'dist/esm/production/middleware.js',
45-
limit: '9.305 KB'
45+
limit: '9.315 KB'
4646
},
4747
{
4848
name: "import * from 'next-intl/routing'",

packages/next-intl/src/middleware/middleware.test.tsx

+46-5
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,14 @@ describe('prefix-based routing', () => {
354354
);
355355
});
356356

357+
it('does not return alternate links when redirecting', () => {
358+
const response = middleware(
359+
createMockRequest('/en', 'en', 'http://localhost:3000', 'de')
360+
);
361+
expect(MockedNextResponse.redirect).toHaveBeenCalled();
362+
expect(response.headers.get('link')).toBe(null);
363+
});
364+
357365
it('sets a cookie when changing to the default locale', () => {
358366
const response = middleware(
359367
createMockRequest('/en', 'en', undefined, 'de')
@@ -3002,7 +3010,7 @@ describe('domain-based routing', () => {
30023010
]);
30033011
expect(
30043012
getLinks(
3005-
createMockRequest('/a-propos', 'fr', 'http://ca.example.com')
3013+
createMockRequest('/fr/a-propos', 'fr', 'http://ca.example.com')
30063014
)
30073015
).toEqual([
30083016
'<http://en.example.com/about>; rel="alternate"; hreflang="en"',
@@ -3045,7 +3053,7 @@ describe('domain-based routing', () => {
30453053
expect(
30463054
getLinks(
30473055
createMockRequest(
3048-
'/fr/produits/apparel/t-shirts',
3056+
'/produits/apparel/t-shirts',
30493057
'fr',
30503058
'http://fr.example.com'
30513059
)
@@ -3246,23 +3254,23 @@ describe('domain-based routing', () => {
32463254
?.split(', ');
32473255
}
32483256

3249-
['/en', '/uk'].forEach((pathname) => {
3257+
['/', '/uk'].forEach((pathname) => {
32503258
expect(getLinks(createMockRequest(pathname))).toEqual([
32513259
'<http://localhost:3000/>; rel="alternate"; hreflang="en"',
32523260
'<http://localhost:3000/uk>; rel="alternate"; hreflang="en-gb"',
32533261
'<http://localhost:3000/>; rel="alternate"; hreflang="x-default"'
32543262
]);
32553263
});
32563264

3257-
['/en/about', '/uk/about'].forEach((pathname) => {
3265+
['/about', '/uk/about'].forEach((pathname) => {
32583266
expect(getLinks(createMockRequest(pathname))).toEqual([
32593267
'<http://localhost:3000/about>; rel="alternate"; hreflang="en"',
32603268
'<http://localhost:3000/uk/about>; rel="alternate"; hreflang="en-gb"',
32613269
'<http://localhost:3000/about>; rel="alternate"; hreflang="x-default"'
32623270
]);
32633271
});
32643272

3265-
expect(getLinks(createMockRequest('/en/unknown'))).toEqual([
3273+
expect(getLinks(createMockRequest('/unknown'))).toEqual([
32663274
'<http://localhost:3000/unknown>; rel="alternate"; hreflang="en"',
32673275
'<http://localhost:3000/uk/unknown>; rel="alternate"; hreflang="en-gb"',
32683276
'<http://localhost:3000/unknown>; rel="alternate"; hreflang="x-default"'
@@ -3374,6 +3382,39 @@ describe('domain-based routing', () => {
33743382
);
33753383
});
33763384

3385+
it('keeps the port when there is a x-forwarded-host', () => {
3386+
createMiddleware({
3387+
defaultLocale: 'en',
3388+
locales: ['en', 'es'],
3389+
domains: [
3390+
{
3391+
domain: 'localhost:3000',
3392+
defaultLocale: 'en',
3393+
locales: ['en']
3394+
},
3395+
{
3396+
domain: 'localhost:3001',
3397+
defaultLocale: 'es',
3398+
locales: ['es']
3399+
}
3400+
]
3401+
})(
3402+
createMockRequest(
3403+
'/en',
3404+
undefined,
3405+
'http://localhost:3001',
3406+
undefined,
3407+
{
3408+
'x-forwarded-host': 'localhost:3001'
3409+
}
3410+
)
3411+
);
3412+
3413+
expect(MockedNextResponse.redirect.mock.calls[0][0].toString()).toBe(
3414+
'http://localhost:3000/en'
3415+
);
3416+
});
3417+
33773418
describe('base path', () => {
33783419
it('redirects non-prefixed requests for the default locale', () => {
33793420
middleware(

packages/next-intl/src/middleware/middleware.tsx

+8-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,11 @@ export default function createMiddleware<
124124
request.headers.get('x-forwarded-proto') ??
125125
request.nextUrl.protocol;
126126

127-
urlObj.port = request.headers.get('x-forwarded-port') ?? '';
127+
const redirectDomainPort = redirectDomain.split(':')[1] as
128+
| string
129+
| undefined;
130+
urlObj.port =
131+
redirectDomainPort ?? request.headers.get('x-forwarded-port') ?? '';
128132
}
129133
}
130134

@@ -135,6 +139,7 @@ export default function createMiddleware<
135139
);
136140
}
137141

142+
hasRedirected = true;
138143
return NextResponse.redirect(urlObj.toString());
139144
}
140145

@@ -158,6 +163,7 @@ export default function createMiddleware<
158163

159164
let response;
160165
let internalTemplateName: string | undefined;
166+
let hasRedirected: boolean | undefined;
161167

162168
let unprefixedInternalPathname = unprefixedExternalPathname;
163169
const pathnames = (resolvedRouting as any).pathnames as
@@ -304,6 +310,7 @@ export default function createMiddleware<
304310
syncCookie(request, response, locale, resolvedRouting, domain);
305311

306312
if (
313+
!hasRedirected &&
307314
resolvedRouting.localePrefix.mode !== 'never' &&
308315
resolvedRouting.alternateLinks &&
309316
resolvedRouting.locales.length > 1

0 commit comments

Comments
 (0)