This repository was archived by the owner on May 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 67
/
Copy pathsetupRedirects.js
91 lines (80 loc) · 3.4 KB
/
setupRedirects.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
const { join } = require("path");
const { existsSync, readFileSync, writeFileSync } = require("fs-extra");
const { logTitle, logItem } = require("../helpers/logger");
const {
CUSTOM_REDIRECTS_PATH,
NEXT_IMAGE_FUNCTION_NAME,
} = require("../config");
const getSortedRoutes = require("../helpers/getSortedRoutes");
const getNetlifyRoutes = require("../helpers/getNetlifyRoutes");
const isRootCatchAllRedirect = require("../helpers/isRootCatchAllRedirect");
// Setup _redirects file that routes all requests to the appropriate location,
// such as one of the Netlify functions or one of the static files.
const setupRedirects = (publishPath) => {
logTitle("🔀 Setting up redirects");
// Collect custom redirects defined by the user
const redirects = [];
if (existsSync(CUSTOM_REDIRECTS_PATH)) {
logItem("# Prepending custom redirects");
redirects.push(readFileSync(CUSTOM_REDIRECTS_PATH, "utf8"));
}
// Collect redirects for NextJS pages
const nextRedirects = [
...require("../pages/api/redirects"),
...require("../pages/getInitialProps/redirects"),
...require("../pages/getServerSideProps/redirects"),
...require("../pages/getStaticProps/redirects"),
...require("../pages/getStaticPropsWithFallback/redirects"),
...require("../pages/getStaticPropsWithRevalidate/redirects"),
...require("../pages/withoutProps/redirects"),
];
// Add next/image redirect to our image function
nextRedirects.push({
route: "/_next/image* url=:url w=:width q=:quality",
target: `/.netlify/functions/${NEXT_IMAGE_FUNCTION_NAME}?url=:url&w=:width&q=:quality`,
});
// Add _redirect section heading
redirects.push("# Next-on-Netlify Redirects");
// Sort routes: More-specific routes (e.g., static routing) precede
// less-specific routes (e.g., catch-all)
const sortedRoutes = getSortedRoutes(nextRedirects.map(({ route }) => route));
// Assemble redirects for each route
sortedRoutes.forEach((route) => {
const nextRedirect = nextRedirects.find(
(redirect) => redirect.route === route && !redirect.added
);
// One route may map to multiple Netlify routes: e.g., catch-all pages
// require two Netlify routes in the _redirects file
getNetlifyRoutes(route).map((netlifyRoute) => {
const {
conditions = [],
force = false,
statusCode = "200",
target,
} = nextRedirect;
const redirectPieces = [
netlifyRoute,
target,
`${statusCode}${force ? "!" : ""}`,
conditions.join(" "),
];
const redirect = redirectPieces.join(" ").trim();
logItem(redirect);
redirects.push(redirect);
// Enables us to add colliding route redirects
nextRedirect.added = true;
});
});
// This takes care of this issue: https://github.com/netlify/next-on-netlify/issues/43
// where the page chunk for a root level catch-all is served incorrectly to the client.
// NOTE: Netlify is also investigating this issue internally.
const hasRootCatchAll = redirects.some(isRootCatchAllRedirect);
if (hasRootCatchAll) {
const rootCatchAllIndex = redirects.findIndex(isRootCatchAllRedirect);
// Add general "no-op" redirect before the root catch-all redirect
redirects.splice(rootCatchAllIndex, 0, "/_next/* /_next/:splat 200");
}
// Write redirects to _redirects file
writeFileSync(join(publishPath, "_redirects"), redirects.join("\n"));
};
module.exports = setupRedirects;