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

Commit 447426d

Browse files
committed
massive cleanup/refactor to transform manifest
1 parent 96959bd commit 447426d

File tree

14 files changed

+273
-347
lines changed

14 files changed

+273
-347
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
const i18n = require("./getI18n")();
2+
const { defaultLocale } = i18n;
3+
4+
// In i18n projects, we need to create redirects from the "naked" route
5+
// to the defaultLocale-prepended route i.e. /static -> /en/static
6+
// Note: there can only one defaultLocale, but we put it in an array to simplify
7+
// logic in redirects.js files via concatenation
8+
const getDefaultLocaleRedirectForI18n = (route, srcRoute, target) => {
9+
// If no i18n, skip
10+
if (!defaultLocale) return [];
11+
12+
const routePieces = route.split("/");
13+
const routeLocale = routePieces[1];
14+
if (routeLocale === defaultLocale) {
15+
const nakedRoute =
16+
route === `/${routeLocale}` ? "/" : route.replace(`/${routeLocale}`, "");
17+
// const nakedRoute = routePieces.slice(2, routePieces.length).join("/");
18+
return [
19+
{
20+
route: nakedRoute,
21+
target: target || route,
22+
},
23+
];
24+
}
25+
26+
return [];
27+
};
28+
29+
module.exports = getDefaultLocaleRedirectForI18n;

lib/helpers/getI18n.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Get the i1i8n details specified in next.config.js, if any
2+
const getNextConfig = require("./getNextConfig");
3+
4+
const getI18n = () => {
5+
const nextConfig = getNextConfig();
6+
7+
return nextConfig.i18n || { locales: [] };
8+
};
9+
10+
module.exports = getI18n;

lib/helpers/getLocaleRoutesForI18n.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const i18n = require("./getI18n")();
2+
const getDataRouteForRoute = require("./getDataRouteForRoute");
3+
4+
const getI18nDataRoute = (route, locale) => {
5+
return route === "/"
6+
? getDataRouteForRoute(`/${locale}`)
7+
: getDataRouteForRoute(route, locale);
8+
};
9+
10+
// In i18n projects, Next does not prepend static routes with locales
11+
// so we have to do it manually
12+
const getLocaleRoutesForI18n = ({ route, srcRoute }) => {
13+
// If no i18n or is dynamic route, skip
14+
if (!i18n.defaultLocale || !!srcRoute) return [];
15+
return i18n.locales.map((locale) => {
16+
return {
17+
route: `/${locale}${route}`,
18+
dataRoute: getI18nDataRoute(route, locale),
19+
nakedRoute: route,
20+
};
21+
});
22+
};
23+
24+
module.exports = getLocaleRoutesForI18n;

lib/helpers/getPrerenderManifest.js

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,46 @@
11
const { join } = require("path");
22
const { readJSONSync } = require("fs-extra");
33
const { NEXT_DIST_DIR } = require("../config");
4+
const nextConfig = require("./getNextConfig")();
5+
const getDataRouteForRoute = require("./getDataRouteForRoute");
6+
7+
const transformManifestForI18n = (manifest) => {
8+
const { routes, dynamicRoutes } = manifest;
9+
const { defaultLocale, locales } = nextConfig.i18n;
10+
const newRoutes = {};
11+
Object.entries(routes).forEach(
12+
([route, { dataRoute, initialRevalidateSeconds, srcRoute }]) => {
13+
const isDynamicRoute = !!srcRoute;
14+
if (isDynamicRoute) {
15+
newRoutes[route] = routes[route];
16+
} else {
17+
locales.forEach((locale) => {
18+
const routeWithPrependedLocale = `/${locale}${route}`;
19+
newRoutes[routeWithPrependedLocale] = {
20+
dataRoute: getDataRouteForRoute(route, locale),
21+
srcRoute: route,
22+
initialRevalidateSeconds: false,
23+
};
24+
});
25+
}
26+
}
27+
);
28+
const newDynamicRoutes = {};
29+
Object.entries(dynamicRoutes).forEach(([route, { dataRoute, fallback }]) => {
30+
newDynamicRoutes[route] = {
31+
route,
32+
dataRoute: getDataRouteForRoute(route, defaultLocale),
33+
fallback,
34+
};
35+
});
36+
37+
return { ...manifest, routes: newRoutes, dynamicRoutes: newDynamicRoutes };
38+
};
439

540
const getPrerenderManifest = () => {
6-
return readJSONSync(join(NEXT_DIST_DIR, "prerender-manifest.json"));
41+
const manifest = readJSONSync(join(NEXT_DIST_DIR, "prerender-manifest.json"));
42+
if (nextConfig.i18n) return transformManifestForI18n(manifest);
43+
return manifest;
744
};
845

946
module.exports = getPrerenderManifest;

lib/helpers/isRouteInPrerenderManifest.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
const getPrerenderManifest = require("./getPrerenderManifest");
2+
const i18n = require("./getI18n")();
23

34
const { routes, dynamicRoutes } = getPrerenderManifest();
5+
const { defaultLocale, locales } = i18n;
6+
7+
const isRouteInManifestWithI18n = (route) => {
8+
let isStaticRoute = false;
9+
Object.entries(routes).forEach(([staticRoute, { srcRoute }]) => {
10+
// This is because in i18n we set the nakedRoute to be the srcRoute in the manifest
11+
if (route === srcRoute) isStaticRoute = true;
12+
});
13+
return isStaticRoute || route in dynamicRoutes;
14+
};
415

516
// Return true if the route is defined in the prerender manifest
617
const isRouteInPrerenderManifest = (route) => {
18+
if (i18n.defaultLocale) return isRouteInManifestWithI18n(route);
719
return route in routes || route in dynamicRoutes;
820
};
921

lib/helpers/isRouteWithDataRoute.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ const getRoutesManifest = require("./getRoutesManifest");
33
const { dataRoutes } = getRoutesManifest();
44

55
// Return true if the route has a data route in the routes manifest
6-
const isRouteInPrerenderManifest = (route) => {
6+
const isRouteWithDataRoute = (route) => {
77
// If no data routes exist, return false
88
if (dataRoutes == null) return false;
99

1010
return dataRoutes.find((dataRoute) => dataRoute.page === route);
1111
};
1212

13-
module.exports = isRouteInPrerenderManifest;
13+
module.exports = isRouteWithDataRoute;

lib/pages/getServerSideProps/redirects.js

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,43 @@
11
const getNetlifyFunctionName = require("../../helpers/getNetlifyFunctionName");
22
const getDataRouteForRoute = require("../../helpers/getDataRouteForRoute");
3+
const getLocaleRoutesForI18n = require("../../helpers/getLocaleRoutesForI18n");
34
const pages = require("./pages");
4-
const nextConfig = require("../../helpers/getNextConfig")();
55

66
const redirects = [];
77

88
/** getServerSideProps pages
99
*
10-
* Params:
11-
* route examples -> '/ssr', '/ssr/[id]'
12-
* filePath examples -> 'pages/ssr.js', 'pages/ssr/[id].js'
13-
*
14-
* With i18n enabled:
15-
* route and filePath formats are the same as above
16-
*
10+
* Page params {
11+
* route -> '/ssr', '/ssr/[id]'
12+
* filePath -> 'pages/ssr.js', 'pages/ssr/[id].js'
13+
* }
1714
**/
1815

1916
pages.forEach(({ route, filePath }) => {
2017
const functionName = getNetlifyFunctionName(filePath);
2118
const target = `/.netlify/functions/${functionName}`;
2219

23-
// If i18n, need to add extra redirects for each locale
24-
// i.e. /en/ssr -> /${target}
25-
if (nextConfig.i18n) {
26-
const { locales = [] } = nextConfig.i18n;
27-
locales.forEach((locale) => {
28-
redirects.push({
29-
route: `/${locale}${route}`,
30-
target,
31-
});
32-
redirects.push({
33-
route:
34-
route === "/"
35-
? getDataRouteForRoute(`/${locale}`)
36-
: getDataRouteForRoute(route, locale),
37-
target,
38-
});
20+
// Add any locale redirects if i18n
21+
getLocaleRoutesForI18n({ route }).forEach((localeRoute) => {
22+
redirects.push({
23+
route: localeRoute.route,
24+
target,
3925
});
40-
}
26+
redirects.push({
27+
route: localeRoute.dataRoute,
28+
target,
29+
});
30+
});
4131

42-
// Add one redirect for the default page/route
32+
// Add one redirect for the naked route
4333
// i.e. /ssr
4434
redirects.push({
4535
route,
4636
target,
4737
});
4838

49-
// Add one redirect for the data route
50-
// Next doesn't provide the dataRoute out of the box for us so we
39+
// Add one redirect for the data route;
40+
// pages-manifest doesn't provide the dataRoute for us so we
5141
// construct it ourselves with getDataRouteForRoute
5242
redirects.push({
5343
route: getDataRouteForRoute(route),

lib/pages/getStaticProps/pages.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
const getPrerenderManifest = require("../../helpers/getPrerenderManifest");
2+
const getLocaleRoutesForI18n = require("../../helpers/getLocaleRoutesForI18n");
23

34
// Collect pages
4-
const pages = [];
5+
let pages = [];
56

67
// Get pages using getStaticProps
78
const { routes } = getPrerenderManifest();

0 commit comments

Comments
 (0)