Skip to content
This repository was archived by the owner on May 10, 2021. It is now read-only.

Commit 3a3ccc7

Browse files
revert route/redirect sorting logic to static then dynamic (#145)
* revert route/redirect sorting logic to static then dynamic * Force redirects with conditions before plain redirects Co-authored-by: Finn Woelm <[email protected]>
1 parent cd1cf9e commit 3a3ccc7

7 files changed

+114
-112
lines changed

Diff for: lib/helpers/getSortedRedirects.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const {
2+
getSortedRoutes: getSortedRoutesFromNext,
3+
} = require("next/dist/next-server/lib/router/utils/sorted-routes");
4+
5+
// Remove the file extension form the route
6+
const removeFileExtension = (route) => route.replace(/\.[a-zA-Z]+$/, "");
7+
8+
// Return an array of redirects sorted in order of specificity, i.e., more generic
9+
// routes precede more specific ones
10+
const getSortedRedirects = (redirects) => {
11+
// The @sls-next getSortedRoutes does not correctly sort routes with file
12+
// endings (e.g., json), so we remove them before sorting and add them back
13+
// after sorting
14+
const routesWithoutExtensions = redirects.map(({ route }) =>
15+
removeFileExtension(route)
16+
);
17+
18+
// Sort the "naked" routes
19+
const sortedRoutes = getSortedRoutesFromNext(routesWithoutExtensions);
20+
21+
// Return original routes in the sorted order
22+
return redirects.sort((a, b) => {
23+
// If routes are different, sort according to Next.js' getSortedRoutes
24+
if (a.route !== b.route) {
25+
return (
26+
sortedRoutes.indexOf(removeFileExtension(a.route)) -
27+
sortedRoutes.indexOf(removeFileExtension(b.route))
28+
);
29+
}
30+
// Otherwise, put the route with more conditions first
31+
return (b.conditions || []).length - (a.conditions || []).length;
32+
});
33+
};
34+
35+
module.exports = getSortedRedirects;

Diff for: lib/helpers/getSortedRoutes.js

-29
This file was deleted.

Diff for: lib/steps/setupRedirects.js

+38-41
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ const {
55
CUSTOM_REDIRECTS_PATH,
66
NEXT_IMAGE_FUNCTION_NAME,
77
} = require("../config");
8-
const getSortedRoutes = require("../helpers/getSortedRoutes");
8+
const getSortedRedirects = require("../helpers/getSortedRedirects");
99
const getNetlifyRoutes = require("../helpers/getNetlifyRoutes");
1010
const isRootCatchAllRedirect = require("../helpers/isRootCatchAllRedirect");
11+
const isDynamicRoute = require("../helpers/isDynamicRoute");
1112

1213
// Setup _redirects file that routes all requests to the appropriate location,
1314
// such as one of the Netlify functions or one of the static files.
@@ -32,53 +33,49 @@ const setupRedirects = (publishPath) => {
3233
...require("../pages/withoutProps/redirects"),
3334
];
3435

36+
// Add _redirect section heading
37+
redirects.push("# Next-on-Netlify Redirects");
38+
39+
const staticRedirects = nextRedirects.filter(
40+
({ route }) => !isDynamicRoute(route)
41+
);
42+
const dynamicRedirects = nextRedirects.filter(({ route }) =>
43+
isDynamicRoute(route)
44+
);
45+
3546
// Add next/image redirect to our image function
36-
nextRedirects.push({
47+
dynamicRedirects.push({
3748
route: "/_next/image* url=:url w=:width q=:quality",
3849
target: `/.netlify/functions/${NEXT_IMAGE_FUNCTION_NAME}?url=:url&w=:width&q=:quality`,
3950
});
4051

41-
// Add _redirect section heading
42-
redirects.push("# Next-on-Netlify Redirects");
43-
44-
// Sort routes: More-specific routes (e.g., static routing) precede
45-
// less-specific routes (e.g., catch-all)
46-
const sortedRoutes = getSortedRoutes(nextRedirects.map(({ route }) => route));
47-
48-
// There may be several redirects with the same route but different targets
49-
const wasRedirectAdded = (redirect) => {
50-
return redirects.find((addedRedirect) => {
51-
const [route, target] = addedRedirect.split(" ");
52-
return redirect.route === route && redirect.target === target;
53-
});
54-
};
52+
const sortedStaticRedirects = getSortedRedirects(staticRedirects);
53+
const sortedDynamicRedirects = getSortedRedirects(dynamicRedirects);
5554

5655
// Assemble redirects for each route
57-
sortedRoutes.forEach((route) => {
58-
const nextRedirect = nextRedirects.find(
59-
(redirect) => redirect.route === route && !wasRedirectAdded(redirect)
60-
);
61-
62-
// One route may map to multiple Netlify routes: e.g., catch-all pages
63-
// require two Netlify routes in the _redirects file
64-
getNetlifyRoutes(route).map((netlifyRoute) => {
65-
const {
66-
conditions = [],
67-
force = false,
68-
statusCode = "200",
69-
target,
70-
} = nextRedirect;
71-
const redirectPieces = [
72-
netlifyRoute,
73-
target,
74-
`${statusCode}${force ? "!" : ""}`,
75-
conditions.join(" "),
76-
];
77-
const redirect = redirectPieces.join(" ").trim();
78-
logItem(redirect);
79-
redirects.push(redirect);
80-
});
81-
});
56+
[...sortedStaticRedirects, ...sortedDynamicRedirects].forEach(
57+
(nextRedirect) => {
58+
// One route may map to multiple Netlify routes: e.g., catch-all pages
59+
// require two Netlify routes in the _redirects file
60+
getNetlifyRoutes(nextRedirect.route).map((netlifyRoute) => {
61+
const {
62+
conditions = [],
63+
force = false,
64+
statusCode = "200",
65+
target,
66+
} = nextRedirect;
67+
const redirectPieces = [
68+
netlifyRoute,
69+
target,
70+
`${statusCode}${force ? "!" : ""}`,
71+
conditions.join(" "),
72+
];
73+
const redirect = redirectPieces.join(" ").trim();
74+
logItem(redirect);
75+
redirects.push(redirect);
76+
});
77+
}
78+
);
8279

8380
// This takes care of this issue: https://github.com/netlify/next-on-netlify/issues/43
8481
// where the page chunk for a root level catch-all is served incorrectly to the client.

Diff for: tests/__snapshots__/defaults.test.js.snap

+9-9
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,8 @@ exports[`Routing creates Netlify redirects 1`] = `
3131
/_next/data/%BUILD_ID%/getStaticProps/withRevalidate/1.json /.netlify/functions/next_getStaticProps_withRevalidate_id 200
3232
/_next/data/%BUILD_ID%/getStaticProps/withRevalidate/2.json /.netlify/functions/next_getStaticProps_withRevalidate_id 200
3333
/_next/data/%BUILD_ID%/getStaticProps/withRevalidate/withFallback/:id.json /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
34-
/_next/image* url=:url w=:width q=:quality /.netlify/functions/next_image?url=:url&w=:width&q=:quality 200
35-
/api/shows/:id /.netlify/functions/next_api_shows_id 200
36-
/api/shows/:params/* /.netlify/functions/next_api_shows_params 200
3734
/api/static /.netlify/functions/next_api_static 200
38-
/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
39-
/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
4035
/getServerSideProps/static /.netlify/functions/next_getServerSideProps_static 200
41-
/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
4236
/getStaticProps/1 /.netlify/functions/next_getStaticProps_id 200! Cookie=__prerender_bypass,__next_preview_data
4337
/getStaticProps/2 /.netlify/functions/next_getStaticProps_id 200! Cookie=__prerender_bypass,__next_preview_data
4438
/getStaticProps/static /.netlify/functions/next_getStaticProps_static 200! Cookie=__prerender_bypass,__next_preview_data
@@ -47,13 +41,19 @@ exports[`Routing creates Netlify redirects 1`] = `
4741
/getStaticProps/withFallback/4 /.netlify/functions/next_getStaticProps_withFallback_id 200! Cookie=__prerender_bypass,__next_preview_data
4842
/getStaticProps/withFallback/my/path/1 /.netlify/functions/next_getStaticProps_withFallback_slug 200! Cookie=__prerender_bypass,__next_preview_data
4943
/getStaticProps/withFallback/my/path/2 /.netlify/functions/next_getStaticProps_withFallback_slug 200! Cookie=__prerender_bypass,__next_preview_data
50-
/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
51-
/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
5244
/getStaticProps/withFallbackBlocking/3 /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200! Cookie=__prerender_bypass,__next_preview_data
5345
/getStaticProps/withFallbackBlocking/4 /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200! Cookie=__prerender_bypass,__next_preview_data
54-
/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
5546
/getStaticProps/withRevalidate/1 /.netlify/functions/next_getStaticProps_withRevalidate_id 200
5647
/getStaticProps/withRevalidate/2 /.netlify/functions/next_getStaticProps_withRevalidate_id 200
48+
/_next/image* url=:url w=:width q=:quality /.netlify/functions/next_image?url=:url&w=:width&q=:quality 200
49+
/api/shows/:id /.netlify/functions/next_api_shows_id 200
50+
/api/shows/:params/* /.netlify/functions/next_api_shows_params 200
51+
/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
52+
/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
53+
/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
54+
/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
55+
/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
56+
/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
5757
/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
5858
/shows/:id /.netlify/functions/next_shows_id 200
5959
/shows/:params/* /.netlify/functions/next_shows_params 200

Diff for: tests/__snapshots__/i18n.test.js.snap

+30-30
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,9 @@ exports[`Routing creates Netlify redirects 1`] = `
4848
/_next/data/%BUILD_ID%/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
4949
/_next/data/%BUILD_ID%/getStaticProps/withFallbackBlocking/:id.json /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
5050
/_next/data/%BUILD_ID%/getStaticProps/withRevalidate/withFallback/:id.json /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
51-
/_next/image* url=:url w=:width q=:quality /.netlify/functions/next_image?url=:url&w=:width&q=:quality 200
52-
/api/shows/:id /.netlify/functions/next_api_shows_id 200
53-
/api/shows/:params/* /.netlify/functions/next_api_shows_params 200
5451
/api/static /.netlify/functions/next_api_static 200
5552
/en /.netlify/functions/next_index 200
56-
/en/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
57-
/en/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
5853
/en/getServerSideProps/static /.netlify/functions/next_getServerSideProps_static 200
59-
/en/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
6054
/en/getStaticProps/1 /.netlify/functions/next_getStaticProps_id 200! Cookie=__prerender_bypass,__next_preview_data
6155
/en/getStaticProps/2 /.netlify/functions/next_getStaticProps_id 200! Cookie=__prerender_bypass,__next_preview_data
6256
/en/getStaticProps/static /.netlify/functions/next_getStaticProps_static 200! Cookie=__prerender_bypass,__next_preview_data
@@ -65,35 +59,15 @@ exports[`Routing creates Netlify redirects 1`] = `
6559
/en/getStaticProps/withFallback/4 /.netlify/functions/next_getStaticProps_withFallback_id 200! Cookie=__prerender_bypass,__next_preview_data
6660
/en/getStaticProps/withFallback/my/path/1 /.netlify/functions/next_getStaticProps_withFallback_slug 200! Cookie=__prerender_bypass,__next_preview_data
6761
/en/getStaticProps/withFallback/my/path/2 /.netlify/functions/next_getStaticProps_withFallback_slug 200! Cookie=__prerender_bypass,__next_preview_data
68-
/en/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
69-
/en/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
7062
/en/getStaticProps/withFallbackBlocking/3 /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200! Cookie=__prerender_bypass,__next_preview_data
7163
/en/getStaticProps/withFallbackBlocking/4 /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200! Cookie=__prerender_bypass,__next_preview_data
72-
/en/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
7364
/en/getStaticProps/withRevalidate/1 /.netlify/functions/next_getStaticProps_withRevalidate_id 200
7465
/en/getStaticProps/withRevalidate/2 /.netlify/functions/next_getStaticProps_withRevalidate_id 200
75-
/en/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
76-
/en/shows/:id /.netlify/functions/next_shows_id 200
77-
/en/shows/:params/* /.netlify/functions/next_shows_params 200
78-
/en/static/:id /en/static/[id].html 200
7966
/es /.netlify/functions/next_index 200
80-
/es/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
81-
/es/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
8267
/es/getServerSideProps/static /.netlify/functions/next_getServerSideProps_static 200
83-
/es/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
8468
/es/getStaticProps/static /.netlify/functions/next_getStaticProps_static 200! Cookie=__prerender_bypass,__next_preview_data
8569
/es/getStaticProps/with-revalidate /.netlify/functions/next_getStaticProps_withrevalidate 200
86-
/es/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
87-
/es/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
88-
/es/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
89-
/es/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
90-
/es/shows/:id /.netlify/functions/next_shows_id 200
91-
/es/shows/:params/* /.netlify/functions/next_shows_params 200
92-
/es/static/:id /es/static/[id].html 200
93-
/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
94-
/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
9570
/getServerSideProps/static /.netlify/functions/next_getServerSideProps_static 200
96-
/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
9771
/getStaticProps/1 /.netlify/functions/next_getStaticProps_id 200! Cookie=__prerender_bypass,__next_preview_data
9872
/getStaticProps/1 /en/getStaticProps/1 200
9973
/getStaticProps/2 /.netlify/functions/next_getStaticProps_id 200! Cookie=__prerender_bypass,__next_preview_data
@@ -109,18 +83,44 @@ exports[`Routing creates Netlify redirects 1`] = `
10983
/getStaticProps/withFallback/my/path/1 /en/getStaticProps/withFallback/my/path/1 200
11084
/getStaticProps/withFallback/my/path/2 /.netlify/functions/next_getStaticProps_withFallback_slug 200! Cookie=__prerender_bypass,__next_preview_data
11185
/getStaticProps/withFallback/my/path/2 /en/getStaticProps/withFallback/my/path/2 200
112-
/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
113-
/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
11486
/getStaticProps/withFallbackBlocking/3 /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200! Cookie=__prerender_bypass,__next_preview_data
11587
/getStaticProps/withFallbackBlocking/3 /en/getStaticProps/withFallbackBlocking/3 200
11688
/getStaticProps/withFallbackBlocking/4 /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200! Cookie=__prerender_bypass,__next_preview_data
11789
/getStaticProps/withFallbackBlocking/4 /en/getStaticProps/withFallbackBlocking/4 200
118-
/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
11990
/getStaticProps/withRevalidate/1 /.netlify/functions/next_getStaticProps_withRevalidate_id 200
12091
/getStaticProps/withRevalidate/2 /.netlify/functions/next_getStaticProps_withRevalidate_id 200
92+
/static /en/static.html 200
93+
/_next/image* url=:url w=:width q=:quality /.netlify/functions/next_image?url=:url&w=:width&q=:quality 200
94+
/api/shows/:id /.netlify/functions/next_api_shows_id 200
95+
/api/shows/:params/* /.netlify/functions/next_api_shows_params 200
96+
/en/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
97+
/en/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
98+
/en/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
99+
/en/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
100+
/en/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
101+
/en/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
102+
/en/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
103+
/en/shows/:id /.netlify/functions/next_shows_id 200
104+
/en/shows/:params/* /.netlify/functions/next_shows_params 200
105+
/en/static/:id /en/static/[id].html 200
106+
/es/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
107+
/es/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
108+
/es/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
109+
/es/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
110+
/es/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
111+
/es/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
112+
/es/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
113+
/es/shows/:id /.netlify/functions/next_shows_id 200
114+
/es/shows/:params/* /.netlify/functions/next_shows_params 200
115+
/es/static/:id /es/static/[id].html 200
116+
/getServerSideProps/all /.netlify/functions/next_getServerSideProps_all_slug 200
117+
/getServerSideProps/all/* /.netlify/functions/next_getServerSideProps_all_slug 200
118+
/getServerSideProps/:id /.netlify/functions/next_getServerSideProps_id 200
119+
/getStaticProps/withFallback/:id /.netlify/functions/next_getStaticProps_withFallback_id 200
120+
/getStaticProps/withFallback/:slug/* /.netlify/functions/next_getStaticProps_withFallback_slug 200
121+
/getStaticProps/withFallbackBlocking/:id /.netlify/functions/next_getStaticProps_withFallbackBlocking_id 200
121122
/getStaticProps/withRevalidate/withFallback/:id /.netlify/functions/next_getStaticProps_withRevalidate_withFallback_id 200
122123
/shows/:id /.netlify/functions/next_shows_id 200
123124
/shows/:params/* /.netlify/functions/next_shows_params 200
124-
/static /en/static.html 200
125125
/static/:id /en/static/[id].html 200"
126126
`;

Diff for: tests/__snapshots__/optionalCatchAll.test.js.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ exports[`Routing creates Netlify redirects 1`] = `
55
/_next/data/%BUILD_ID%/page.json /.netlify/functions/next_page 200
66
/_next/data/%BUILD_ID%/index.json /.netlify/functions/next_all 200
77
/_next/data/%BUILD_ID%/* /.netlify/functions/next_all 200
8-
/_next/image* url=:url w=:width q=:quality /.netlify/functions/next_image?url=:url&w=:width&q=:quality 200
98
/page /.netlify/functions/next_page 200
9+
/_next/image* url=:url w=:width q=:quality /.netlify/functions/next_image?url=:url&w=:width&q=:quality 200
1010
/ /.netlify/functions/next_all 200
1111
/_next/* /_next/:splat 200
1212
/* /.netlify/functions/next_all 200"

Diff for: tests/staticIndexPages.test.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,7 @@ describe("Routing", () => {
8787
expect(redirects[3]).toEqual(
8888
"/_next/data/%BUILD_ID%/static.json /.netlify/functions/next_static 200! Cookie=__prerender_bypass,__next_preview_data"
8989
);
90-
// [4] is the next_image redirect
91-
expect(redirects[5]).toEqual(
90+
expect(redirects[4]).toEqual(
9291
"/static /.netlify/functions/next_static 200! Cookie=__prerender_bypass,__next_preview_data"
9392
);
9493
});

0 commit comments

Comments
 (0)