Skip to content

Commit f3d6033

Browse files
authored
[next]: add flag for behavior introduced in #12916 (#12941)
This flags the behavior introduced in: - #12916 With it by default being disabled to minimize the risk of the change.
1 parent 1e98464 commit f3d6033

File tree

22 files changed

+1141
-15
lines changed

22 files changed

+1141
-15
lines changed

.changeset/giant-melons-speak.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@vercel/next': patch
3+
---
4+
5+
flag behavior to defer defaultLocale rewrite

packages/next/src/server-build.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,9 @@ export async function serverBuild({
201201
const experimentalAllowBundling = Boolean(
202202
process.env.NEXT_EXPERIMENTAL_FUNCTION_BUNDLING
203203
);
204+
const skipDefaultLocaleRewrite = Boolean(
205+
process.env.NEXT_EXPERIMENTAL_DEFER_DEFAULT_LOCALE_REWRITE
206+
);
204207

205208
const lambdas: { [key: string]: Lambda } = {};
206209
const prerenders: { [key: string]: Prerender } = {};
@@ -1941,6 +1944,14 @@ export async function serverBuild({
19411944
},
19421945
continue: true,
19431946
},
1947+
]
1948+
: []),
1949+
1950+
// We only want to add these rewrites before user redirects
1951+
// when `skipDefaultLocaleRewrite` is not flagged on
1952+
// and when localeDetection is enabled.
1953+
...(!skipDefaultLocaleRewrite || i18n.localeDetection !== false
1954+
? [
19441955
{
19451956
src: `^${path.posix.join('/', entryDirectory)}$`,
19461957
dest: `${path.posix.join(
@@ -2254,7 +2265,9 @@ export async function serverBuild({
22542265
// to allow checking non-prefixed lambda outputs
22552266
...(i18n
22562267
? [
2257-
...(i18n.localeDetection === false
2268+
// When `skipDefaultLocaleRewrite` is flagged on and localeDetection is disabled,
2269+
// we only want to add the rewrite as the fallback case once routing is complete.
2270+
...(skipDefaultLocaleRewrite && i18n.localeDetection === false
22582271
? [
22592272
{
22602273
src: `^${path.posix.join('/', entryDirectory)}$`,

packages/next/src/utils.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ export const MAX_UNCOMPRESSED_LAMBDA_SIZE = !isNaN(
6262
? Number(process.env.MAX_UNCOMPRESSED_LAMBDA_SIZE)
6363
: DEFAULT_MAX_UNCOMPRESSED_LAMBDA_SIZE;
6464

65+
const skipDefaultLocaleRewrite = Boolean(
66+
process.env.NEXT_EXPERIMENTAL_DEFER_DEFAULT_LOCALE_REWRITE
67+
);
68+
6569
// Identify /[param]/ in route string
6670
// eslint-disable-next-line no-useless-escape
6771
const TEST_DYNAMIC_ROUTE = /\/\[[^\/]+?\](?=\/|$)/;
@@ -583,7 +587,11 @@ export function localizeDynamicRoutes(
583587
// when locale detection is disabled we don't add the default locale
584588
// to the path while resolving routes so we need to be able to match
585589
// without it being present
586-
if (isLocalePrefixed && routesManifest?.i18n?.localeDetection === false) {
590+
if (
591+
skipDefaultLocaleRewrite &&
592+
isLocalePrefixed &&
593+
routesManifest?.i18n?.localeDetection === false
594+
) {
587595
const nonLocalePrefixedRoute = JSON.parse(JSON.stringify(route));
588596
nonLocalePrefixedRoute.src = nonLocalePrefixedRoute.src.replace(
589597
'^',
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const path = require('path');
2+
const { deployAndTest } = require('../../utils');
3+
const fetch = require('../../../../../test/lib/deployment/fetch-retry');
4+
5+
const ctx = {};
6+
7+
describe(`${__dirname.split(path.sep).pop()}`, () => {
8+
beforeAll(async () => {
9+
const info = await deployAndTest(__dirname);
10+
11+
Object.assign(ctx, info);
12+
});
13+
14+
it('should not clobber a user-provided redirect with a default locale rewrite', async () => {
15+
const res = await fetch(ctx.deploymentUrl, {
16+
redirect: 'manual',
17+
headers: {
18+
'x-redirect-me': '1',
19+
},
20+
});
21+
expect(res.status).toEqual(307);
22+
expect(res.headers.get('location')).toEqual(`${ctx.deploymentUrl}/fr-BE`);
23+
});
24+
});
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
module.exports = {
2+
generateBuildId() {
3+
return 'testing-build-id';
4+
},
5+
async redirects() {
6+
return [
7+
{
8+
source: '/',
9+
has: [
10+
{
11+
type: 'header',
12+
key: 'x-redirect-me',
13+
},
14+
],
15+
destination: '/fr-BE',
16+
permanent: false,
17+
locale: false,
18+
},
19+
{
20+
source: '/:path+',
21+
has: [
22+
{
23+
type: 'header',
24+
key: 'x-redirect-me',
25+
},
26+
],
27+
destination: '/fr-BE/:path+',
28+
permanent: false,
29+
locale: false,
30+
},
31+
];
32+
},
33+
i18n: {
34+
localeDetection: false,
35+
locales: ['nl-NL', 'nl-BE', 'nl', 'fr-BE', 'fr', 'en-US', 'en'],
36+
defaultLocale: 'en-US',
37+
// TODO: testing locale domains support, will require custom
38+
// testing set-up as test accounts are used currently
39+
domains: [
40+
{
41+
domain: 'example.be',
42+
defaultLocale: 'nl-BE',
43+
},
44+
{
45+
domain: 'example.fr',
46+
defaultLocale: 'fr',
47+
},
48+
],
49+
},
50+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"dependencies": {
3+
"next": "canary",
4+
"react": "latest",
5+
"react-dom": "latest"
6+
},
7+
"ignoreNextjsUpdates": true
8+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Link from 'next/link';
2+
import { useRouter } from 'next/router';
3+
4+
export default function Page(props) {
5+
const router = useRouter();
6+
7+
return (
8+
<>
9+
<p id="another">another page</p>
10+
<p id="props">{JSON.stringify(props)}</p>
11+
<p id="router-locale">{router.locale}</p>
12+
<p id="router-locales">{JSON.stringify(router.locales)}</p>
13+
<p id="router-query">{JSON.stringify(router.query)}</p>
14+
<p id="router-pathname">{router.pathname}</p>
15+
<p id="router-as-path">{router.asPath}</p>
16+
<Link href="/">
17+
<a id="to-index">to /</a>
18+
</Link>
19+
<br />
20+
</>
21+
);
22+
}
23+
24+
export const getServerSideProps = ({ locale, locales }) => {
25+
return {
26+
props: {
27+
locale,
28+
locales,
29+
},
30+
};
31+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Link from 'next/link';
2+
import { useRouter } from 'next/router';
3+
4+
export default function Page(props) {
5+
const router = useRouter();
6+
7+
return (
8+
<>
9+
<p id="auto-export">auto-export page</p>
10+
<p id="props">{JSON.stringify(props)}</p>
11+
<p id="router-locale">{router.locale}</p>
12+
<p id="router-locales">{JSON.stringify(router.locales)}</p>
13+
<p id="router-query">{JSON.stringify(router.query)}</p>
14+
<p id="router-pathname">{router.pathname}</p>
15+
<p id="router-as-path">{router.asPath}</p>
16+
<Link href="/">
17+
<a id="to-index">to /</a>
18+
</Link>
19+
</>
20+
);
21+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { useRouter } from 'next/router';
2+
3+
export default function Dynamic(props) {
4+
const router = useRouter();
5+
6+
return (
7+
<>
8+
<p>dynamic page</p>
9+
<p id="query">{JSON.stringify(router.query)}</p>
10+
</>
11+
);
12+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import Link from 'next/link';
2+
3+
const Slug = props => {
4+
return (
5+
<div>
6+
<p id="props">{JSON.stringify(props)}</p>
7+
<Link href="/gsp/blocking/hallo-wereld" locale={'nl-NL'}>
8+
<a>/nl-NL/gsp/blocking/hallo-wereld</a>
9+
</Link>
10+
<br />
11+
<Link href="/gsp/blocking/42" locale={'nl-NL'}>
12+
<a>/nl-NL/gsp/blocking/42</a>
13+
</Link>
14+
<br />
15+
<Link href="/gsp/blocking/hallo-welt" locale={'fr'}>
16+
<a>/fr/gsp/blocking/hallo-welt</a>
17+
</Link>
18+
<br />
19+
<Link href="/gsp/blocking/42" locale={'fr'}>
20+
<a>/fr/gsp/blocking/42</a>
21+
</Link>
22+
</div>
23+
);
24+
};
25+
26+
export const getStaticProps = () => {
27+
return {
28+
props: {
29+
random: Math.random() + Date.now(),
30+
catchall: 'yes',
31+
},
32+
revalidate: 1,
33+
};
34+
};
35+
36+
export const getStaticPaths = () => {
37+
return {
38+
paths: [],
39+
fallback: 'blocking',
40+
};
41+
};
42+
43+
export default Slug;

0 commit comments

Comments
 (0)