Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial changes for i18n support #17370

Merged
merged 16 commits into from Oct 7, 2020
Merged

Add initial changes for i18n support #17370

merged 16 commits into from Oct 7, 2020

Conversation

ijjk
Copy link
Member

@ijjk ijjk commented Sep 26, 2020

This adds the initial changes outlined in the i18n routing RFC. This currently treats the locale prefix on routes similar to how the basePath is treated in that the config doesn't require any changes to your pages directory and is automatically stripped/added based on the detected locale that should be used.

Currently redirecting occurs on the / route if a locale is detected regardless of if an optional catch-all route would match the / route or not we may want to investigate whether we want to disable this redirection automatically if an /index.js file isn't present at root of the pages directory.

TODO:

  • ensure locale detection/populating works in serverless mode correctly
  • add tests for locale handling in different modes, fallback/getStaticProps/getServerSideProps

To be continued in fall-up PRs

  • add tests for revalidate, auto-export, basePath + i18n
  • add mapping of domains with locales
  • investigate detecting locale against non-index routes and populating the locale in a cookie

x-ref: #17110

# Conflicts:
#	packages/next/next-server/server/config.ts
#	packages/next/next-server/server/next-server.ts
#	packages/next/package.json
@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk
Copy link
Member Author

ijjk commented Sep 28, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
buildDuration 13.1s 13.7s ⚠️ +592ms
nodeModulesSize 62.9 MB 63 MB ⚠️ +127 kB
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js add/i18n Change
/ failed reqs 0 0
/ total time (seconds) 2.598 2.573 -0.02
/ avg req/sec 962.42 971.79 +9.37
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.613 1.619 ⚠️ +0.01
/error-in-render avg req/sec 1550.13 1544.17 ⚠️ -5.96
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..9339.js gzip 10.9 kB 11.1 kB ⚠️ +160 B
framework.HASH.js gzip 39 kB 39 kB
main-e3dd5fc..bc67.js gzip 7.16 kB 7.35 kB ⚠️ +189 B
webpack-e067..f178.js gzip 751 B 751 B
Overall change 57.8 kB 58.1 kB ⚠️ +349 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..dule.js gzip 6.77 kB 6.91 kB ⚠️ +139 B
framework.HA..dule.js gzip 39 kB 39 kB
main-f4d7a25..dule.js gzip 6.23 kB 6.42 kB ⚠️ +188 B
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.7 kB 53 kB ⚠️ +327 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/i18n Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.32 kB ⚠️ +12 B
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.72 kB ⚠️ +12 B
Client Pages Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.28 kB ⚠️ +13 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.37 kB ⚠️ +13 B
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_buildManifest.js gzip 322 B 323 B ⚠️ +1 B
_buildManife..dule.js gzip 329 B 330 B ⚠️ +1 B
Overall change 651 B 653 B ⚠️ +2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary ijjk/next.js add/i18n Change
index.html gzip 1 kB 1 kB -1 B
link.html gzip 1.01 kB 1.01 kB -1 B
withRouter.html gzip 996 B 995 B -1 B
Overall change 3.01 kB 3.01 kB -3 B

Diffs

Diff for _buildManifest.js
@@ -7,7 +7,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-32658e75d53af2daa2e0.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-943a64e08fa49f0674ac.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -10,7 +10,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-cb038f0ac2e648ce4861.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-776abc716b587eb0f923.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-32658e7..af2daa2e0.js
@@ -311,7 +311,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           props.passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
-          childProps.href = (0, _router.addBasePath)(as);
+          childProps.href = (0, _router.addBasePath)(
+            (0, _router.addLocale)(as, router && router.locale)
+          );
         }
 
         return /*#__PURE__*/ _react["default"].cloneElement(child, childProps);
Diff for link-cb038f0..61.module.js
@@ -292,7 +292,9 @@
           props.passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
-          childProps.href = (0, _router.addBasePath)(as);
+          childProps.href = (0, _router.addBasePath)(
+            (0, _router.addLocale)(as, router && router.locale)
+          );
         }
 
         return /*#__PURE__*/ _react.default.cloneElement(child, childProps);
Diff for 677f882d2ed8..5fa35cac6.js
@@ -691,6 +691,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       var _createClass = __webpack_require__("W8MJ");
 
       exports.__esModule = true;
+      exports.addLocale = addLocale;
+      exports.delLocale = delLocale;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
@@ -744,17 +746,33 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function addPathPrefix(path, prefix) {
+        return prefix && path.startsWith("/")
+          ? path === "/"
+            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(prefix)
+            : "".concat(prefix).concat(path)
+          : path;
+      }
+
+      function addLocale(path, locale) {
+        return locale && !path.startsWith("/" + locale)
+          ? addPathPrefix(path, "/" + locale)
+          : path;
+      }
+
+      function delLocale(path, locale) {
+        return locale && path.startsWith("/" + locale)
+          ? path.substr(locale.length + 1) || "/"
+          : path;
+      }
+
       function hasBasePath(path) {
         return path === basePath || path.startsWith(basePath + "/");
       }
 
       function addBasePath(path) {
         // we only add the basepath on relative urls
-        return basePath && path.startsWith("/")
-          ? path === "/"
-            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(basePath)
-            : basePath + path
-          : path;
+        return addPathPrefix(path, basePath);
       }
 
       function delBasePath(path) {
@@ -975,7 +993,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             initialStyleSheets = _ref.initialStyleSheets,
             err = _ref.err,
             subscription = _ref.subscription,
-            isFallback = _ref.isFallback;
+            isFallback = _ref.isFallback,
+            locale = _ref.locale,
+            locales = _ref.locales;
 
           _classCallCheck(this, Router);
 
@@ -996,6 +1016,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = void 0;
           this._inFlightRoute = void 0;
           this._shallow = void 0;
+          this.locale = void 0;
+          this.locales = void 0;
 
           this.onPopState = function(e) {
             var state = e.state;
@@ -1106,6 +1128,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.isSsr = true;
           this.isFallback = isFallback;
+          this.locale = locale;
+          this.locales = locales;
 
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
@@ -1263,7 +1287,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               this.abortComponentLoad(this._inFlightRoute);
                             }
 
-                            cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
+                            as = addLocale(as, this.locale);
+                            cleanedAs = delLocale(
+                              hasBasePath(as) ? delBasePath(as) : as,
+                              this.locale
+                            );
                             this._inFlightRoute = as; // If the url change is only related to a hash change
                             // We should not proceed. We should only change the state.
                             // WARNING: `_h` is an internal option for handing Next.js client-side
@@ -1273,7 +1301,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (
                               !(!options._h && this.onlyAHashChange(cleanedAs))
                             ) {
-                              _context.next = 16;
+                              _context.next = 17;
                               break;
                             }
 
@@ -1286,16 +1314,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             Router.events.emit("hashChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 16:
-                            _context.next = 18;
+                          case 17:
+                            _context.next = 19;
                             return this.pageLoader.getPageList();
 
-                          case 18:
+                          case 19:
                             pages = _context.sent;
-                            _context.next = 21;
+                            _context.next = 22;
                             return this.pageLoader.promisedBuildManifest;
 
-                          case 21:
+                          case 22:
                             _yield$this$pageLoade = _context.sent;
                             rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = (0, _parseRelativeUrl.parseRelativeUrl)(
@@ -1344,10 +1372,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            resolvedAs = delBasePath(resolvedAs);
+                            resolvedAs = delLocale(
+                              delBasePath(resolvedAs),
+                              this.locale
+                            );
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 49;
+                              _context.next = 50;
                               break;
                             }
 
@@ -1370,7 +1401,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 (shouldInterpolate && !interpolatedAs.result)
                               )
                             ) {
-                              _context.next = 48;
+                              _context.next = 49;
                               break;
                             }
 
@@ -1381,7 +1412,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 46;
+                              _context.next = 47;
                               break;
                             }
 
@@ -1412,11 +1443,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 )
                             );
 
-                          case 46:
-                            _context.next = 49;
+                          case 47:
+                            _context.next = 50;
                             break;
 
-                          case 48:
+                          case 49:
                             if (shouldInterpolate) {
                               as = (0, _utils.formatWithValidation)(
                                 Object.assign({}, parsedAs, {
@@ -1432,10 +1463,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Object.assign(query, routeMatch);
                             }
 
-                          case 49:
+                          case 50:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 50;
-                            _context.next = 53;
+                            _context.prev = 51;
+                            _context.next = 54;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1444,7 +1475,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 53:
+                          case 54:
                             routeInfo = _context.sent;
                             (error = routeInfo.error),
                               (props = routeInfo.props),
@@ -1459,7 +1490,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 props.pageProps.__N_REDIRECT
                               )
                             ) {
-                              _context.next = 64;
+                              _context.next = 65;
                               break;
                             }
 
@@ -1468,7 +1499,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             // it's not
 
                             if (!destination.startsWith("/")) {
-                              _context.next = 62;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1478,7 +1509,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             this._resolveHref(parsedHref, pages);
 
                             if (!pages.includes(parsedHref.pathname)) {
-                              _context.next = 62;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1492,21 +1523,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )
                             );
 
-                          case 62:
+                          case 63:
                             window.location.href = destination;
                             return _context.abrupt(
                               "return",
                               new Promise(function() {})
                             );
 
-                          case 64:
+                          case 65:
                             Router.events.emit("beforeHistoryChange", as);
-                            this.changeState(method, url, as, options);
+                            this.changeState(
+                              method,
+                              url,
+                              addLocale(as, this.locale),
+                              options
+                            );
 
                             if (false) {
                             }
 
-                            _context.next = 69;
+                            _context.next = 70;
                             return this.set(
                               route,
                               pathname,
@@ -1518,9 +1554,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               else throw e;
                             });
 
-                          case 69:
+                          case 70:
                             if (!error) {
-                              _context.next = 72;
+                              _context.next = 73;
                               break;
                             }
 
@@ -1531,28 +1567,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 72:
+                          case 73:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 77:
-                            _context.prev = 77;
-                            _context.t0 = _context["catch"](50);
+                          case 78:
+                            _context.prev = 78;
+                            _context.t0 = _context["catch"](51);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 81;
+                              _context.next = 82;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 81:
+                          case 82:
                             throw _context.t0;
 
-                          case 82:
+                          case 83:
                           case "end":
                             return _context.stop();
                         }
@@ -1560,7 +1596,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[50, 77]]
+                    [[51, 78]]
                   );
                 })
               );
@@ -1837,7 +1873,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   query: query
                                 }),
                                 delBasePath(as),
-                                __N_SSG
+                                __N_SSG,
+                                this.locale
                               );
                             }
 
@@ -3527,7 +3564,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         "asPath",
         "components",
         "isFallback",
-        "basePath"
+        "basePath",
+        "locale",
+        "locales"
       ];
       var routerEvents = [
         "routeChangeStart",
@@ -3647,7 +3686,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var property = _step.value;
 
             if (typeof _router[property] === "object") {
-              instance[property] = Object.assign({}, _router[property]); // makes sure query is not stateful
+              instance[property] = Object.assign(
+                Array.isArray(_router[property]) ? [] : {},
+                _router[property]
+              ); // makes sure query is not stateful
 
               continue;
             }
Diff for 677f882d2ed8..aa.module.js
@@ -552,6 +552,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       "use strict";
 
       exports.__esModule = true;
+      exports.addLocale = addLocale;
+      exports.delLocale = delLocale;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
@@ -605,17 +607,33 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function addPathPrefix(path, prefix) {
+        return prefix && path.startsWith("/")
+          ? path === "/"
+            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(prefix)
+            : "".concat(prefix).concat(path)
+          : path;
+      }
+
+      function addLocale(path, locale) {
+        return locale && !path.startsWith("/" + locale)
+          ? addPathPrefix(path, "/" + locale)
+          : path;
+      }
+
+      function delLocale(path, locale) {
+        return locale && path.startsWith("/" + locale)
+          ? path.substr(locale.length + 1) || "/"
+          : path;
+      }
+
       function hasBasePath(path) {
         return path === basePath || path.startsWith(basePath + "/");
       }
 
       function addBasePath(path) {
         // we only add the basepath on relative urls
-        return basePath && path.startsWith("/")
-          ? path === "/"
-            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(basePath)
-            : basePath + path
-          : path;
+        return addPathPrefix(path, basePath);
       }
 
       function delBasePath(path) {
@@ -828,7 +846,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             initialStyleSheets,
             err,
             subscription,
-            isFallback
+            isFallback,
+            locale,
+            locales
           } = _ref;
           this.route = void 0;
           this.pathname = void 0;
@@ -847,6 +867,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = void 0;
           this._inFlightRoute = void 0;
           this._shallow = void 0;
+          this.locale = void 0;
+          this.locales = void 0;
 
           this.onPopState = e => {
             var state = e.state;
@@ -950,6 +972,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.isSsr = true;
           this.isFallback = isFallback;
+          this.locale = locale;
+          this.locales = locales;
 
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
@@ -1043,7 +1067,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
+          as = addLocale(as, this.locale);
+          var cleanedAs = delLocale(
+            hasBasePath(as) ? delBasePath(as) : as,
+            this.locale
+          );
           this._inFlightRoute = as; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
@@ -1103,7 +1131,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var potentialHref;
           }
 
-          resolvedAs = delBasePath(resolvedAs);
+          resolvedAs = delLocale(delBasePath(resolvedAs), this.locale);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var parsedAs = (0, _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
@@ -1204,7 +1232,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             Router.events.emit("beforeHistoryChange", as);
-            this.changeState(method, url, as, options);
+            this.changeState(method, url, addLocale(as, this.locale), options);
 
             if (false) {
               var appComp;
@@ -1351,7 +1379,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   query
                 }),
                 delBasePath(as),
-                __N_SSG
+                __N_SSG,
+                this.locale
               );
             }
 
@@ -1897,7 +1926,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         "asPath",
         "components",
         "isFallback",
-        "basePath"
+        "basePath",
+        "locale",
+        "locales"
       ];
       var routerEvents = [
         "routeChangeStart",
@@ -2009,7 +2040,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
         for (var property of urlPropertyFields) {
           if (typeof _router[property] === "object") {
-            instance[property] = Object.assign({}, _router[property]); // makes sure query is not stateful
+            instance[property] = Object.assign(
+              Array.isArray(_router[property]) ? [] : {},
+              _router[property]
+            ); // makes sure query is not stateful
 
             continue;
           }
Diff for main-51cdbd9..0a.module.js
@@ -43,6 +43,33 @@
       /***/
     },
 
+    /***/ "3wub": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.normalizeLocalePath = normalizeLocalePath;
+
+      function normalizeLocalePath(pathname, locales) {
+        var detectedLocale;
+        (locales || []).some(locale => {
+          if (pathname.startsWith("/".concat(locale))) {
+            detectedLocale = locale;
+            pathname =
+              pathname.replace(new RegExp("^/".concat(locale)), "") || "/";
+            return true;
+          }
+
+          return false;
+        });
+        return {
+          pathname,
+          detectedLocale
+        };
+      }
+
+      /***/
+    },
+
     /***/ BMP1: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -221,6 +248,8 @@
 
       var _headManagerContext = __webpack_require__("FYa8");
 
+      var _normalizeLocalePath = __webpack_require__("3wub");
+
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _routerContext = __webpack_require__("qOIg");
@@ -262,8 +291,10 @@
         runtimeConfig,
         dynamicIds,
         isFallback,
-        head: initialHeadData
+        head: initialHeadData,
+        locales
       } = data;
+      var { locale } = data;
       var prefix = assetPrefix || ""; // With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
       // So, this is how we do it in the client side at runtime
 
@@ -280,6 +311,20 @@
         asPath = (0, _router.delBasePath)(asPath);
       }
 
+      asPath = (0, _router.delLocale)(asPath, locale);
+
+      if (isFallback && locales) {
+        var localePathResult = (0, _normalizeLocalePath.normalizeLocalePath)(
+          asPath,
+          locales
+        );
+
+        if (localePathResult.detectedLocale) {
+          asPath = asPath.substr(localePathResult.detectedLocale.length + 1);
+          locale = localePathResult.detectedLocale;
+        }
+      }
+
       var pageLoader = new _pageLoader.default(buildId, prefix, page);
 
       var register = _ref => {
@@ -472,7 +517,9 @@
                 props,
                 err
               });
-            }
+            },
+            locale,
+            locales
           }
         ); // call init-client middleware
 
@@ -1390,7 +1437,7 @@
          * @param {string} asPath the URL as shown in browser (virtual path); used for dynamic routes
          */
 
-        getDataHref(href, asPath, ssg) {
+        getDataHref(href, asPath, ssg, locale) {
           var { pathname: hrefPathname, query, search } = (0,
           _parseRelativeUrl.parseRelativeUrl)(href);
           var { pathname: asPathname } = (0,
@@ -1398,7 +1445,10 @@
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug = path => {
-            var dataRoute = (0, _getAssetPathFromRoute.default)(path, ".json");
+            var dataRoute = (0, _router.addLocale)(
+              (0, _getAssetPathFromRoute.default)(path, ".json"),
+              locale
+            );
             return (0, _router.addBasePath)(
               "/_next/data/"
                 .concat(this.buildId)
Diff for main-907d40a..21fba96be.js
@@ -43,6 +43,33 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       /***/
     },
 
+    /***/ "3wub": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.normalizeLocalePath = normalizeLocalePath;
+
+      function normalizeLocalePath(pathname, locales) {
+        var detectedLocale;
+        (locales || []).some(function(locale) {
+          if (pathname.startsWith("/".concat(locale))) {
+            detectedLocale = locale;
+            pathname =
+              pathname.replace(new RegExp("^/".concat(locale)), "") || "/";
+            return true;
+          }
+
+          return false;
+        });
+        return {
+          pathname: pathname,
+          detectedLocale: detectedLocale
+        };
+      }
+
+      /***/
+    },
+
     /***/ "7W2i": /***/ function(module, exports, __webpack_require__) {
       var setPrototypeOf = __webpack_require__("SksO");
 
@@ -304,6 +331,8 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _headManagerContext = __webpack_require__("FYa8");
 
+      var _normalizeLocalePath = __webpack_require__("3wub");
+
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _routerContext = __webpack_require__("qOIg");
@@ -344,7 +373,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         runtimeConfig = data.runtimeConfig,
         dynamicIds = data.dynamicIds,
         isFallback = data.isFallback,
-        initialHeadData = data.head;
+        initialHeadData = data.head,
+        locales = data.locales;
+      var locale = data.locale;
       var prefix = assetPrefix || ""; // With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
       // So, this is how we do it in the client side at runtime
 
@@ -361,6 +392,20 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         asPath = (0, _router.delBasePath)(asPath);
       }
 
+      asPath = (0, _router.delLocale)(asPath, locale);
+
+      if (isFallback && locales) {
+        var localePathResult = (0, _normalizeLocalePath.normalizeLocalePath)(
+          asPath,
+          locales
+        );
+
+        if (localePathResult.detectedLocale) {
+          asPath = asPath.substr(localePathResult.detectedLocale.length + 1);
+          locale = localePathResult.detectedLocale;
+        }
+      }
+
       var pageLoader = new _pageLoader["default"](buildId, prefix, page);
 
       var register = function register(_ref) {
@@ -654,7 +699,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
                               props: props,
                               err: err
                             });
-                          }
+                          },
+                          locale: locale,
+                          locales: locales
                         }
                       ); // call init-client middleware
 
@@ -1745,7 +1792,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           },
           {
             key: "getDataHref",
-            value: function getDataHref(href, asPath, ssg) {
+            value: function getDataHref(href, asPath, ssg, locale) {
               var _this2 = this;
 
               var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
@@ -1759,9 +1806,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               var route = normalizeRoute(hrefPathname);
 
               var getHrefForSlug = function getHrefForSlug(path) {
-                var dataRoute = (0, _getAssetPathFromRoute["default"])(
-                  path,
-                  ".json"
+                var dataRoute = (0, _router.addLocale)(
+                  (0, _getAssetPathFromRoute["default"])(path, ".json"),
+                  locale
                 );
                 return (0, _router.addBasePath)(
                   "/_next/data/"
Diff for index.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-51cdbd96932b5cca840a.module.js"
+      href="/_next/static/chunks/main-0636bfd30cc32dda65f5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.bf9428fc983a2622e844.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -85,13 +85,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-907d40a118a21fba96be.js"
+      src="/_next/static/chunks/main-a9a40c7f131bb7118c93.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-51cdbd96932b5cca840a.module.js"
+      src="/_next/static/chunks/main-0636bfd30cc32dda65f5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e3c2cb5a316641a464d7.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.bf9428fc983a2622e844.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-51cdbd96932b5cca840a.module.js"
+      href="/_next/static/chunks/main-0636bfd30cc32dda65f5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.bf9428fc983a2622e844.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-cb038f0ac2e648ce4861.module.js"
+      href="/_next/static/chunks/pages/link-776abc716b587eb0f923.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -90,13 +90,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-907d40a118a21fba96be.js"
+      src="/_next/static/chunks/main-a9a40c7f131bb7118c93.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-51cdbd96932b5cca840a.module.js"
+      src="/_next/static/chunks/main-0636bfd30cc32dda65f5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -126,13 +126,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e3c2cb5a316641a464d7.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.bf9428fc983a2622e844.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -150,13 +150,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-32658e75d53af2daa2e0.js"
+      src="/_next/static/chunks/pages/link-943a64e08fa49f0674ac.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-cb038f0ac2e648ce4861.module.js"
+      src="/_next/static/chunks/pages/link-776abc716b587eb0f923.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-51cdbd96932b5cca840a.module.js"
+      href="/_next/static/chunks/main-0636bfd30cc32dda65f5.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.bf9428fc983a2622e844.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -85,13 +85,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-907d40a118a21fba96be.js"
+      src="/_next/static/chunks/main-a9a40c7f131bb7118c93.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-51cdbd96932b5cca840a.module.js"
+      src="/_next/static/chunks/main-0636bfd30cc32dda65f5.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e3c2cb5a316641a464d7.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.bf9428fc983a2622e844.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
buildDuration 15s 14.8s -179ms
nodeModulesSize 62.9 MB 63 MB ⚠️ +127 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..9339.js gzip 10.9 kB N/A N/A
framework.HASH.js gzip 39 kB 39 kB
main-e3dd5fc..bc67.js gzip 7.16 kB N/A N/A
webpack-e067..f178.js gzip 751 B 751 B
677f882d2ed8..3df1.js gzip N/A 11.1 kB N/A
main-5a619a8..6773.js gzip N/A 7.35 kB N/A
Overall change 57.8 kB 58.1 kB ⚠️ +349 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..dule.js gzip 6.77 kB N/A N/A
framework.HA..dule.js gzip 39 kB 39 kB
main-f4d7a25..dule.js gzip 6.23 kB N/A N/A
webpack-07c5..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.91 kB N/A
main-fc0e71d..dule.js gzip N/A 6.42 kB N/A
Overall change 52.7 kB 53 kB ⚠️ +327 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/i18n Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB N/A N/A
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
link-537beac..0f9a.js gzip N/A 1.32 kB N/A
Overall change 7.71 kB 7.72 kB ⚠️ +12 B
Client Pages Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
link-02f45f5..dule.js gzip N/A 1.28 kB N/A
Overall change 5.36 kB 5.37 kB ⚠️ +13 B
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_buildManifest.js gzip 322 B 323 B ⚠️ +1 B
_buildManife..dule.js gzip 329 B 330 B ⚠️ +1 B
Overall change 651 B 653 B ⚠️ +2 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_error.js 1.05 MB 1.05 MB ⚠️ +404 B
404.html 4.34 kB 4.34 kB
hooks.html 3.92 kB 3.92 kB
index.js 1.05 MB 1.05 MB ⚠️ +404 B
link.js 1.1 MB 1.1 MB ⚠️ +1.18 kB
routerDirect.js 1.09 MB 1.09 MB ⚠️ +1.13 kB
withRouter.js 1.09 MB 1.09 MB ⚠️ +1.13 kB
Overall change 5.4 MB 5.41 MB ⚠️ +4.24 kB
Commit: 32e5f95

@ijjk
Copy link
Member Author

ijjk commented Oct 3, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
buildDuration 13.2s 13.1s -90ms
nodeModulesSize 63.1 MB 63.3 MB ⚠️ +134 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
/ failed reqs 0 0
/ total time (seconds) 2.517 2.643 ⚠️ +0.13
/ avg req/sec 993.05 945.92 ⚠️ -47.13
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.49 1.581 ⚠️ +0.09
/error-in-render avg req/sec 1677.86 1581.21 ⚠️ -96.65
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..9339.js gzip 10.9 kB 11 kB ⚠️ +124 B
framework.HASH.js gzip 39 kB 39 kB
main-d493e7d..42f5.js gzip 7.17 kB 7.21 kB ⚠️ +43 B
webpack-e067..f178.js gzip 751 B 751 B
Overall change 57.8 kB 58 kB ⚠️ +167 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..dule.js gzip 6.77 kB 6.87 kB ⚠️ +108 B
framework.HA..dule.js gzip 39 kB 39 kB
main-f8905d4..dule.js gzip 6.24 kB 6.28 kB ⚠️ +38 B
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.7 kB 52.9 kB ⚠️ +146 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/i18n Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.32 kB ⚠️ +12 B
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.72 kB ⚠️ +12 B
Client Pages Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.28 kB ⚠️ +13 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.37 kB ⚠️ +13 B
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_buildManifest.js gzip 322 B 323 B ⚠️ +1 B
_buildManife..dule.js gzip 329 B 330 B ⚠️ +1 B
Overall change 651 B 653 B ⚠️ +2 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
index.html gzip 1 kB 1 kB
link.html gzip 1.01 kB 1.01 kB ⚠️ +1 B
withRouter.html gzip 996 B 996 B
Overall change 3.01 kB 3.01 kB ⚠️ +1 B

Diffs

Diff for _buildManifest.js
@@ -7,7 +7,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-32658e75d53af2daa2e0.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-943a64e08fa49f0674ac.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -10,7 +10,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-cb038f0ac2e648ce4861.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-776abc716b587eb0f923.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-32658e7..af2daa2e0.js
@@ -311,7 +311,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           props.passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
-          childProps.href = (0, _router.addBasePath)(as);
+          childProps.href = (0, _router.addBasePath)(
+            (0, _router.addLocale)(as, router && router.locale)
+          );
         }
 
         return /*#__PURE__*/ _react["default"].cloneElement(child, childProps);
Diff for link-cb038f0..61.module.js
@@ -292,7 +292,9 @@
           props.passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
-          childProps.href = (0, _router.addBasePath)(as);
+          childProps.href = (0, _router.addBasePath)(
+            (0, _router.addLocale)(as, router && router.locale)
+          );
         }
 
         return /*#__PURE__*/ _react.default.cloneElement(child, childProps);
Diff for 677f882d2ed8..5fa35cac6.js
@@ -691,6 +691,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       var _createClass = __webpack_require__("W8MJ");
 
       exports.__esModule = true;
+      exports.addLocale = addLocale;
+      exports.delLocale = delLocale;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
@@ -744,17 +746,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function addPathPrefix(path, prefix) {
+        return prefix && path.startsWith("/")
+          ? path === "/"
+            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(prefix)
+            : "".concat(prefix).concat(path)
+          : path;
+      }
+
+      function addLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
+      function delLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
       function hasBasePath(path) {
         return path === basePath || path.startsWith(basePath + "/");
       }
 
       function addBasePath(path) {
         // we only add the basepath on relative urls
-        return basePath && path.startsWith("/")
-          ? path === "/"
-            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(basePath)
-            : basePath + path
-          : path;
+        return addPathPrefix(path, basePath);
       }
 
       function delBasePath(path) {
@@ -975,7 +995,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             initialStyleSheets = _ref.initialStyleSheets,
             err = _ref.err,
             subscription = _ref.subscription,
-            isFallback = _ref.isFallback;
+            isFallback = _ref.isFallback,
+            locale = _ref.locale,
+            locales = _ref.locales;
 
           _classCallCheck(this, Router);
 
@@ -996,6 +1018,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = void 0;
           this._inFlightRoute = void 0;
           this._shallow = void 0;
+          this.locale = void 0;
+          this.locales = void 0;
 
           this.onPopState = function(e) {
             var state = e.state;
@@ -1107,6 +1131,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isSsr = true;
           this.isFallback = isFallback;
 
+          if (false) {
+          }
+
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
@@ -1263,7 +1290,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               this.abortComponentLoad(this._inFlightRoute);
                             }
 
-                            cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
+                            as = addLocale(as, this.locale);
+                            cleanedAs = delLocale(
+                              hasBasePath(as) ? delBasePath(as) : as,
+                              this.locale
+                            );
                             this._inFlightRoute = as; // If the url change is only related to a hash change
                             // We should not proceed. We should only change the state.
                             // WARNING: `_h` is an internal option for handing Next.js client-side
@@ -1273,7 +1304,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (
                               !(!options._h && this.onlyAHashChange(cleanedAs))
                             ) {
-                              _context.next = 16;
+                              _context.next = 17;
                               break;
                             }
 
@@ -1286,16 +1317,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             Router.events.emit("hashChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 16:
-                            _context.next = 18;
+                          case 17:
+                            _context.next = 19;
                             return this.pageLoader.getPageList();
 
-                          case 18:
+                          case 19:
                             pages = _context.sent;
-                            _context.next = 21;
+                            _context.next = 22;
                             return this.pageLoader.promisedBuildManifest;
 
-                          case 21:
+                          case 22:
                             _yield$this$pageLoade = _context.sent;
                             rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = (0, _parseRelativeUrl.parseRelativeUrl)(
@@ -1344,10 +1375,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            resolvedAs = delBasePath(resolvedAs);
+                            resolvedAs = delLocale(
+                              delBasePath(resolvedAs),
+                              this.locale
+                            );
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 49;
+                              _context.next = 50;
                               break;
                             }
 
@@ -1370,7 +1404,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 (shouldInterpolate && !interpolatedAs.result)
                               )
                             ) {
-                              _context.next = 48;
+                              _context.next = 49;
                               break;
                             }
 
@@ -1381,7 +1415,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 46;
+                              _context.next = 47;
                               break;
                             }
 
@@ -1412,11 +1446,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 )
                             );
 
-                          case 46:
-                            _context.next = 49;
+                          case 47:
+                            _context.next = 50;
                             break;
 
-                          case 48:
+                          case 49:
                             if (shouldInterpolate) {
                               as = (0, _utils.formatWithValidation)(
                                 Object.assign({}, parsedAs, {
@@ -1432,10 +1466,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Object.assign(query, routeMatch);
                             }
 
-                          case 49:
+                          case 50:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 50;
-                            _context.next = 53;
+                            _context.prev = 51;
+                            _context.next = 54;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1444,7 +1478,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 53:
+                          case 54:
                             routeInfo = _context.sent;
                             (error = routeInfo.error),
                               (props = routeInfo.props),
@@ -1459,7 +1493,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 props.pageProps.__N_REDIRECT
                               )
                             ) {
-                              _context.next = 64;
+                              _context.next = 65;
                               break;
                             }
 
@@ -1468,7 +1502,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             // it's not
 
                             if (!destination.startsWith("/")) {
-                              _context.next = 62;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1478,7 +1512,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             this._resolveHref(parsedHref, pages);
 
                             if (!pages.includes(parsedHref.pathname)) {
-                              _context.next = 62;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1492,21 +1526,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )
                             );
 
-                          case 62:
+                          case 63:
                             window.location.href = destination;
                             return _context.abrupt(
                               "return",
                               new Promise(function() {})
                             );
 
-                          case 64:
+                          case 65:
                             Router.events.emit("beforeHistoryChange", as);
-                            this.changeState(method, url, as, options);
+                            this.changeState(
+                              method,
+                              url,
+                              addLocale(as, this.locale),
+                              options
+                            );
 
                             if (false) {
                             }
 
-                            _context.next = 69;
+                            _context.next = 70;
                             return this.set(
                               route,
                               pathname,
@@ -1518,9 +1557,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               else throw e;
                             });
 
-                          case 69:
+                          case 70:
                             if (!error) {
-                              _context.next = 72;
+                              _context.next = 73;
                               break;
                             }
 
@@ -1531,28 +1570,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 72:
+                          case 73:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 77:
-                            _context.prev = 77;
-                            _context.t0 = _context["catch"](50);
+                          case 78:
+                            _context.prev = 78;
+                            _context.t0 = _context["catch"](51);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 81;
+                              _context.next = 82;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 81:
+                          case 82:
                             throw _context.t0;
 
-                          case 82:
+                          case 83:
                           case "end":
                             return _context.stop();
                         }
@@ -1560,7 +1599,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[50, 77]]
+                    [[51, 78]]
                   );
                 })
               );
@@ -1837,7 +1876,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   query: query
                                 }),
                                 delBasePath(as),
-                                __N_SSG
+                                __N_SSG,
+                                this.locale
                               );
                             }
 
@@ -3527,7 +3567,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         "asPath",
         "components",
         "isFallback",
-        "basePath"
+        "basePath",
+        "locale",
+        "locales"
       ];
       var routerEvents = [
         "routeChangeStart",
@@ -3647,7 +3689,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var property = _step.value;
 
             if (typeof _router[property] === "object") {
-              instance[property] = Object.assign({}, _router[property]); // makes sure query is not stateful
+              instance[property] = Object.assign(
+                Array.isArray(_router[property]) ? [] : {},
+                _router[property]
+              ); // makes sure query is not stateful
 
               continue;
             }
Diff for 677f882d2ed8..aa.module.js
@@ -552,6 +552,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       "use strict";
 
       exports.__esModule = true;
+      exports.addLocale = addLocale;
+      exports.delLocale = delLocale;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
@@ -605,17 +607,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function addPathPrefix(path, prefix) {
+        return prefix && path.startsWith("/")
+          ? path === "/"
+            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(prefix)
+            : "".concat(prefix).concat(path)
+          : path;
+      }
+
+      function addLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
+      function delLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
       function hasBasePath(path) {
         return path === basePath || path.startsWith(basePath + "/");
       }
 
       function addBasePath(path) {
         // we only add the basepath on relative urls
-        return basePath && path.startsWith("/")
-          ? path === "/"
-            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(basePath)
-            : basePath + path
-          : path;
+        return addPathPrefix(path, basePath);
       }
 
       function delBasePath(path) {
@@ -828,7 +848,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             initialStyleSheets,
             err,
             subscription,
-            isFallback
+            isFallback,
+            locale,
+            locales
           } = _ref;
           this.route = void 0;
           this.pathname = void 0;
@@ -847,6 +869,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = void 0;
           this._inFlightRoute = void 0;
           this._shallow = void 0;
+          this.locale = void 0;
+          this.locales = void 0;
 
           this.onPopState = e => {
             var state = e.state;
@@ -951,6 +975,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isSsr = true;
           this.isFallback = isFallback;
 
+          if (false) {
+          }
+
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
@@ -1043,7 +1070,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
+          as = addLocale(as, this.locale);
+          var cleanedAs = delLocale(
+            hasBasePath(as) ? delBasePath(as) : as,
+            this.locale
+          );
           this._inFlightRoute = as; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
@@ -1103,7 +1134,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var potentialHref;
           }
 
-          resolvedAs = delBasePath(resolvedAs);
+          resolvedAs = delLocale(delBasePath(resolvedAs), this.locale);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var parsedAs = (0, _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
@@ -1204,7 +1235,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             Router.events.emit("beforeHistoryChange", as);
-            this.changeState(method, url, as, options);
+            this.changeState(method, url, addLocale(as, this.locale), options);
 
             if (false) {
               var appComp;
@@ -1351,7 +1382,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   query
                 }),
                 delBasePath(as),
-                __N_SSG
+                __N_SSG,
+                this.locale
               );
             }
 
@@ -1897,7 +1929,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         "asPath",
         "components",
         "isFallback",
-        "basePath"
+        "basePath",
+        "locale",
+        "locales"
       ];
       var routerEvents = [
         "routeChangeStart",
@@ -2009,7 +2043,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
         for (var property of urlPropertyFields) {
           if (typeof _router[property] === "object") {
-            instance[property] = Object.assign({}, _router[property]); // makes sure query is not stateful
+            instance[property] = Object.assign(
+              Array.isArray(_router[property]) ? [] : {},
+              _router[property]
+            ); // makes sure query is not stateful
 
             continue;
           }
Diff for main-1638ee9..a9.module.js
@@ -270,8 +270,10 @@
         runtimeConfig,
         dynamicIds,
         isFallback,
-        head: initialHeadData
+        head: initialHeadData,
+        locales
       } = data;
+      var { locale } = data;
       var prefix = assetPrefix || ""; // With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
       // So, this is how we do it in the client side at runtime
 
@@ -288,6 +290,12 @@
         asPath = (0, _router.delBasePath)(asPath);
       }
 
+      asPath = (0, _router.delLocale)(asPath, locale);
+
+      if (false) {
+        var localePathResult, normalizeLocalePath;
+      }
+
       var pageLoader = new _pageLoader.default(buildId, prefix, page);
 
       var register = _ref => {
@@ -480,7 +488,9 @@
                 props,
                 err
               });
-            }
+            },
+            locale,
+            locales
           }
         ); // call init-client middleware
 
@@ -1398,7 +1408,7 @@
          * @param {string} asPath the URL as shown in browser (virtual path); used for dynamic routes
          */
 
-        getDataHref(href, asPath, ssg) {
+        getDataHref(href, asPath, ssg, locale) {
           var { pathname: hrefPathname, query, search } = (0,
           _parseRelativeUrl.parseRelativeUrl)(href);
           var { pathname: asPathname } = (0,
@@ -1406,7 +1416,10 @@
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug = path => {
-            var dataRoute = (0, _getAssetPathFromRoute.default)(path, ".json");
+            var dataRoute = (0, _router.addLocale)(
+              (0, _getAssetPathFromRoute.default)(path, ".json"),
+              locale
+            );
             return (0, _router.addBasePath)(
               "/_next/data/"
                 .concat(this.buildId)
Diff for main-7f74095..c7a3b6f9a.js
@@ -352,7 +352,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         runtimeConfig = data.runtimeConfig,
         dynamicIds = data.dynamicIds,
         isFallback = data.isFallback,
-        initialHeadData = data.head;
+        initialHeadData = data.head,
+        locales = data.locales;
+      var locale = data.locale;
       var prefix = assetPrefix || ""; // With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
       // So, this is how we do it in the client side at runtime
 
@@ -369,6 +371,12 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         asPath = (0, _router.delBasePath)(asPath);
       }
 
+      asPath = (0, _router.delLocale)(asPath, locale);
+
+      if (false) {
+        var localePathResult, _require, normalizeLocalePath;
+      }
+
       var pageLoader = new _pageLoader["default"](buildId, prefix, page);
 
       var register = function register(_ref) {
@@ -493,7 +501,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               if (true) {
                 return this.props.children;
               } else {
-                var _require, ReactDevOverlay;
+                var _require2, ReactDevOverlay;
               }
             }
           }
@@ -514,9 +522,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               mod,
               initialErr,
               _yield$pageLoader$loa2,
-              _require2,
-              isValidElementType,
               _require3,
+              isValidElementType,
+              _require4,
               getNodeError,
               renderCtx,
               _args = arguments;
@@ -593,14 +601,14 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
                         break;
                       }
 
-                      (_require2 = __webpack_require__(
+                      (_require3 = __webpack_require__(
                         !(function webpackMissingModule() {
                           var e = new Error("Cannot find module 'react-is'");
                           e.code = "MODULE_NOT_FOUND";
                           throw e;
                         })()
                       )),
-                        (isValidElementType = _require2.isValidElementType);
+                        (isValidElementType = _require3.isValidElementType);
 
                       if (isValidElementType(CachedComponent)) {
                         _context.next = 21;
@@ -662,7 +670,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
                               props: props,
                               err: err
                             });
-                          }
+                          },
+                          locale: locale,
+                          locales: locales
                         }
                       ); // call init-client middleware
 
@@ -1753,7 +1763,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           },
           {
             key: "getDataHref",
-            value: function getDataHref(href, asPath, ssg) {
+            value: function getDataHref(href, asPath, ssg, locale) {
               var _this2 = this;
 
               var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
@@ -1767,9 +1777,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               var route = normalizeRoute(hrefPathname);
 
               var getHrefForSlug = function getHrefForSlug(path) {
-                var dataRoute = (0, _getAssetPathFromRoute["default"])(
-                  path,
-                  ".json"
+                var dataRoute = (0, _router.addLocale)(
+                  (0, _getAssetPathFromRoute["default"])(path, ".json"),
+                  locale
                 );
                 return (0, _router.addBasePath)(
                   "/_next/data/"
Diff for index.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      href="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -85,13 +85,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-7f740958d0cc7a3b6f9a.js"
+      src="/_next/static/chunks/main-f6e906adc67b584d1ee1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      src="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4a47cb7dd0a29df91531.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      href="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-cb038f0ac2e648ce4861.module.js"
+      href="/_next/static/chunks/pages/link-776abc716b587eb0f923.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -90,13 +90,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-7f740958d0cc7a3b6f9a.js"
+      src="/_next/static/chunks/main-f6e906adc67b584d1ee1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      src="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -126,13 +126,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4a47cb7dd0a29df91531.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -150,13 +150,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-32658e75d53af2daa2e0.js"
+      src="/_next/static/chunks/pages/link-943a64e08fa49f0674ac.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-cb038f0ac2e648ce4861.module.js"
+      src="/_next/static/chunks/pages/link-776abc716b587eb0f923.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      href="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -85,13 +85,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-7f740958d0cc7a3b6f9a.js"
+      src="/_next/static/chunks/main-f6e906adc67b584d1ee1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      src="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4a47cb7dd0a29df91531.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
buildDuration 15.2s 14.7s -506ms
nodeModulesSize 63.1 MB 63.3 MB ⚠️ +134 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..9339.js gzip 10.9 kB N/A N/A
framework.HASH.js gzip 39 kB 39 kB
main-d493e7d..42f5.js gzip 7.17 kB N/A N/A
webpack-e067..f178.js gzip 751 B 751 B
677f882d2ed8..977d.js gzip N/A 11 kB N/A
main-77437a1..b2c8.js gzip N/A 7.21 kB N/A
Overall change 57.8 kB 58 kB ⚠️ +167 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..dule.js gzip 6.77 kB N/A N/A
framework.HA..dule.js gzip 39 kB 39 kB
main-f8905d4..dule.js gzip 6.24 kB N/A N/A
webpack-07c5..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.87 kB N/A
main-9ca6a23..dule.js gzip N/A 6.28 kB N/A
Overall change 52.7 kB 52.9 kB ⚠️ +146 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/i18n Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB N/A N/A
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
link-537beac..0f9a.js gzip N/A 1.32 kB N/A
Overall change 7.71 kB 7.72 kB ⚠️ +12 B
Client Pages Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
link-02f45f5..dule.js gzip N/A 1.28 kB N/A
Overall change 5.36 kB 5.37 kB ⚠️ +13 B
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_buildManifest.js gzip 322 B 323 B ⚠️ +1 B
_buildManife..dule.js gzip 329 B 330 B ⚠️ +1 B
Overall change 651 B 653 B ⚠️ +2 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_error.js 1.05 MB 1.05 MB ⚠️ +806 B
404.html 4.34 kB 4.34 kB
hooks.html 3.92 kB 3.92 kB
index.js 1.05 MB 1.05 MB ⚠️ +806 B
link.js 1.1 MB 1.1 MB ⚠️ +1.42 kB
routerDirect.js 1.09 MB 1.09 MB ⚠️ +1.37 kB
withRouter.js 1.09 MB 1.09 MB ⚠️ +1.37 kB
Overall change 5.4 MB 5.41 MB ⚠️ +5.77 kB
Commit: de94016

@ijjk ijjk marked this pull request as ready for review October 3, 2020 02:00
@ijjk ijjk requested review from lfades and Timer as code owners October 3, 2020 02:00
@ijjk ijjk requested a review from timneutkens October 3, 2020 02:00
kodiakhq bot pushed a commit that referenced this pull request Oct 4, 2020
Noticed this method was left-over from previous query handling logic in `api-utils` while working on #17370 so this removes the extra code which should be safe since `api-utils` is an internal file that shouldn't be relied on externally.
@ijjk
Copy link
Member Author

ijjk commented Oct 5, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
buildDuration 14.4s 14.1s -379ms
nodeModulesSize 63.2 MB 63.3 MB ⚠️ +134 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
/ failed reqs 0 0
/ total time (seconds) 2.717 2.705 -0.01
/ avg req/sec 920.04 924.21 +4.17
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.579 1.654 ⚠️ +0.07
/error-in-render avg req/sec 1583.73 1511.32 ⚠️ -72.41
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..9339.js gzip 10.9 kB 11 kB ⚠️ +124 B
framework.HASH.js gzip 39 kB 39 kB
main-d493e7d..42f5.js gzip 7.17 kB 7.21 kB ⚠️ +43 B
webpack-e067..f178.js gzip 751 B 751 B
Overall change 57.8 kB 58 kB ⚠️ +167 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..dule.js gzip 6.77 kB 6.87 kB ⚠️ +108 B
framework.HA..dule.js gzip 39 kB 39 kB
main-f8905d4..dule.js gzip 6.24 kB 6.28 kB ⚠️ +38 B
webpack-07c5..dule.js gzip 751 B 751 B
Overall change 52.7 kB 52.9 kB ⚠️ +146 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/i18n Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB 1.32 kB ⚠️ +12 B
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
Overall change 7.71 kB 7.72 kB ⚠️ +12 B
Client Pages Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB 1.28 kB ⚠️ +13 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.37 kB ⚠️ +13 B
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_buildManifest.js gzip 322 B 323 B ⚠️ +1 B
_buildManife..dule.js gzip 329 B 330 B ⚠️ +1 B
Overall change 651 B 653 B ⚠️ +2 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
index.html gzip 1 kB 1 kB
link.html gzip 1.01 kB 1.01 kB ⚠️ +1 B
withRouter.html gzip 996 B 996 B
Overall change 3.01 kB 3.01 kB ⚠️ +1 B

Diffs

Diff for _buildManifest.js
@@ -7,7 +7,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-32658e75d53af2daa2e0.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-943a64e08fa49f0674ac.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -10,7 +10,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-cb038f0ac2e648ce4861.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-776abc716b587eb0f923.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-32658e7..af2daa2e0.js
@@ -311,7 +311,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           props.passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
-          childProps.href = (0, _router.addBasePath)(as);
+          childProps.href = (0, _router.addBasePath)(
+            (0, _router.addLocale)(as, router && router.locale)
+          );
         }
 
         return /*#__PURE__*/ _react["default"].cloneElement(child, childProps);
Diff for link-cb038f0..61.module.js
@@ -292,7 +292,9 @@
           props.passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
-          childProps.href = (0, _router.addBasePath)(as);
+          childProps.href = (0, _router.addBasePath)(
+            (0, _router.addLocale)(as, router && router.locale)
+          );
         }
 
         return /*#__PURE__*/ _react.default.cloneElement(child, childProps);
Diff for 677f882d2ed8..5fa35cac6.js
@@ -691,6 +691,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       var _createClass = __webpack_require__("W8MJ");
 
       exports.__esModule = true;
+      exports.addLocale = addLocale;
+      exports.delLocale = delLocale;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
@@ -744,17 +746,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function addPathPrefix(path, prefix) {
+        return prefix && path.startsWith("/")
+          ? path === "/"
+            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(prefix)
+            : "".concat(prefix).concat(path)
+          : path;
+      }
+
+      function addLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
+      function delLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
       function hasBasePath(path) {
         return path === basePath || path.startsWith(basePath + "/");
       }
 
       function addBasePath(path) {
         // we only add the basepath on relative urls
-        return basePath && path.startsWith("/")
-          ? path === "/"
-            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(basePath)
-            : basePath + path
-          : path;
+        return addPathPrefix(path, basePath);
       }
 
       function delBasePath(path) {
@@ -975,7 +995,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             initialStyleSheets = _ref.initialStyleSheets,
             err = _ref.err,
             subscription = _ref.subscription,
-            isFallback = _ref.isFallback;
+            isFallback = _ref.isFallback,
+            locale = _ref.locale,
+            locales = _ref.locales;
 
           _classCallCheck(this, Router);
 
@@ -996,6 +1018,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = void 0;
           this._inFlightRoute = void 0;
           this._shallow = void 0;
+          this.locale = void 0;
+          this.locales = void 0;
 
           this.onPopState = function(e) {
             var state = e.state;
@@ -1107,6 +1131,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isSsr = true;
           this.isFallback = isFallback;
 
+          if (false) {
+          }
+
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
@@ -1263,7 +1290,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               this.abortComponentLoad(this._inFlightRoute);
                             }
 
-                            cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
+                            as = addLocale(as, this.locale);
+                            cleanedAs = delLocale(
+                              hasBasePath(as) ? delBasePath(as) : as,
+                              this.locale
+                            );
                             this._inFlightRoute = as; // If the url change is only related to a hash change
                             // We should not proceed. We should only change the state.
                             // WARNING: `_h` is an internal option for handing Next.js client-side
@@ -1273,7 +1304,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (
                               !(!options._h && this.onlyAHashChange(cleanedAs))
                             ) {
-                              _context.next = 16;
+                              _context.next = 17;
                               break;
                             }
 
@@ -1286,16 +1317,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             Router.events.emit("hashChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 16:
-                            _context.next = 18;
+                          case 17:
+                            _context.next = 19;
                             return this.pageLoader.getPageList();
 
-                          case 18:
+                          case 19:
                             pages = _context.sent;
-                            _context.next = 21;
+                            _context.next = 22;
                             return this.pageLoader.promisedBuildManifest;
 
-                          case 21:
+                          case 22:
                             _yield$this$pageLoade = _context.sent;
                             rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = (0, _parseRelativeUrl.parseRelativeUrl)(
@@ -1344,10 +1375,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            resolvedAs = delBasePath(resolvedAs);
+                            resolvedAs = delLocale(
+                              delBasePath(resolvedAs),
+                              this.locale
+                            );
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 49;
+                              _context.next = 50;
                               break;
                             }
 
@@ -1370,7 +1404,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 (shouldInterpolate && !interpolatedAs.result)
                               )
                             ) {
-                              _context.next = 48;
+                              _context.next = 49;
                               break;
                             }
 
@@ -1381,7 +1415,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 46;
+                              _context.next = 47;
                               break;
                             }
 
@@ -1412,11 +1446,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 )
                             );
 
-                          case 46:
-                            _context.next = 49;
+                          case 47:
+                            _context.next = 50;
                             break;
 
-                          case 48:
+                          case 49:
                             if (shouldInterpolate) {
                               as = (0, _utils.formatWithValidation)(
                                 Object.assign({}, parsedAs, {
@@ -1432,10 +1466,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Object.assign(query, routeMatch);
                             }
 
-                          case 49:
+                          case 50:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 50;
-                            _context.next = 53;
+                            _context.prev = 51;
+                            _context.next = 54;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1444,7 +1478,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 53:
+                          case 54:
                             routeInfo = _context.sent;
                             (error = routeInfo.error),
                               (props = routeInfo.props),
@@ -1459,7 +1493,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 props.pageProps.__N_REDIRECT
                               )
                             ) {
-                              _context.next = 64;
+                              _context.next = 65;
                               break;
                             }
 
@@ -1468,7 +1502,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             // it's not
 
                             if (!destination.startsWith("/")) {
-                              _context.next = 62;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1478,7 +1512,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             this._resolveHref(parsedHref, pages);
 
                             if (!pages.includes(parsedHref.pathname)) {
-                              _context.next = 62;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1492,21 +1526,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )
                             );
 
-                          case 62:
+                          case 63:
                             window.location.href = destination;
                             return _context.abrupt(
                               "return",
                               new Promise(function() {})
                             );
 
-                          case 64:
+                          case 65:
                             Router.events.emit("beforeHistoryChange", as);
-                            this.changeState(method, url, as, options);
+                            this.changeState(
+                              method,
+                              url,
+                              addLocale(as, this.locale),
+                              options
+                            );
 
                             if (false) {
                             }
 
-                            _context.next = 69;
+                            _context.next = 70;
                             return this.set(
                               route,
                               pathname,
@@ -1518,9 +1557,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               else throw e;
                             });
 
-                          case 69:
+                          case 70:
                             if (!error) {
-                              _context.next = 72;
+                              _context.next = 73;
                               break;
                             }
 
@@ -1531,28 +1570,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 72:
+                          case 73:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 77:
-                            _context.prev = 77;
-                            _context.t0 = _context["catch"](50);
+                          case 78:
+                            _context.prev = 78;
+                            _context.t0 = _context["catch"](51);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 81;
+                              _context.next = 82;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 81:
+                          case 82:
                             throw _context.t0;
 
-                          case 82:
+                          case 83:
                           case "end":
                             return _context.stop();
                         }
@@ -1560,7 +1599,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[50, 77]]
+                    [[51, 78]]
                   );
                 })
               );
@@ -1837,7 +1876,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   query: query
                                 }),
                                 delBasePath(as),
-                                __N_SSG
+                                __N_SSG,
+                                this.locale
                               );
                             }
 
@@ -3527,7 +3567,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         "asPath",
         "components",
         "isFallback",
-        "basePath"
+        "basePath",
+        "locale",
+        "locales"
       ];
       var routerEvents = [
         "routeChangeStart",
@@ -3647,7 +3689,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var property = _step.value;
 
             if (typeof _router[property] === "object") {
-              instance[property] = Object.assign({}, _router[property]); // makes sure query is not stateful
+              instance[property] = Object.assign(
+                Array.isArray(_router[property]) ? [] : {},
+                _router[property]
+              ); // makes sure query is not stateful
 
               continue;
             }
Diff for 677f882d2ed8..aa.module.js
@@ -552,6 +552,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       "use strict";
 
       exports.__esModule = true;
+      exports.addLocale = addLocale;
+      exports.delLocale = delLocale;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
@@ -605,17 +607,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function addPathPrefix(path, prefix) {
+        return prefix && path.startsWith("/")
+          ? path === "/"
+            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(prefix)
+            : "".concat(prefix).concat(path)
+          : path;
+      }
+
+      function addLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
+      function delLocale(path, locale) {
+        if (false) {
+        }
+
+        return path;
+      }
+
       function hasBasePath(path) {
         return path === basePath || path.startsWith(basePath + "/");
       }
 
       function addBasePath(path) {
         // we only add the basepath on relative urls
-        return basePath && path.startsWith("/")
-          ? path === "/"
-            ? (0, _normalizeTrailingSlash.normalizePathTrailingSlash)(basePath)
-            : basePath + path
-          : path;
+        return addPathPrefix(path, basePath);
       }
 
       function delBasePath(path) {
@@ -828,7 +848,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             initialStyleSheets,
             err,
             subscription,
-            isFallback
+            isFallback,
+            locale,
+            locales
           } = _ref;
           this.route = void 0;
           this.pathname = void 0;
@@ -847,6 +869,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = void 0;
           this._inFlightRoute = void 0;
           this._shallow = void 0;
+          this.locale = void 0;
+          this.locales = void 0;
 
           this.onPopState = e => {
             var state = e.state;
@@ -951,6 +975,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isSsr = true;
           this.isFallback = isFallback;
 
+          if (false) {
+          }
+
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
@@ -1043,7 +1070,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
+          as = addLocale(as, this.locale);
+          var cleanedAs = delLocale(
+            hasBasePath(as) ? delBasePath(as) : as,
+            this.locale
+          );
           this._inFlightRoute = as; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
@@ -1103,7 +1134,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var potentialHref;
           }
 
-          resolvedAs = delBasePath(resolvedAs);
+          resolvedAs = delLocale(delBasePath(resolvedAs), this.locale);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var parsedAs = (0, _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
@@ -1204,7 +1235,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             Router.events.emit("beforeHistoryChange", as);
-            this.changeState(method, url, as, options);
+            this.changeState(method, url, addLocale(as, this.locale), options);
 
             if (false) {
               var appComp;
@@ -1351,7 +1382,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   query
                 }),
                 delBasePath(as),
-                __N_SSG
+                __N_SSG,
+                this.locale
               );
             }
 
@@ -1897,7 +1929,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         "asPath",
         "components",
         "isFallback",
-        "basePath"
+        "basePath",
+        "locale",
+        "locales"
       ];
       var routerEvents = [
         "routeChangeStart",
@@ -2009,7 +2043,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
         for (var property of urlPropertyFields) {
           if (typeof _router[property] === "object") {
-            instance[property] = Object.assign({}, _router[property]); // makes sure query is not stateful
+            instance[property] = Object.assign(
+              Array.isArray(_router[property]) ? [] : {},
+              _router[property]
+            ); // makes sure query is not stateful
 
             continue;
           }
Diff for main-1638ee9..a9.module.js
@@ -270,8 +270,10 @@
         runtimeConfig,
         dynamicIds,
         isFallback,
-        head: initialHeadData
+        head: initialHeadData,
+        locales
       } = data;
+      var { locale } = data;
       var prefix = assetPrefix || ""; // With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
       // So, this is how we do it in the client side at runtime
 
@@ -288,6 +290,12 @@
         asPath = (0, _router.delBasePath)(asPath);
       }
 
+      asPath = (0, _router.delLocale)(asPath, locale);
+
+      if (false) {
+        var localePathResult, normalizeLocalePath;
+      }
+
       var pageLoader = new _pageLoader.default(buildId, prefix, page);
 
       var register = _ref => {
@@ -480,7 +488,9 @@
                 props,
                 err
               });
-            }
+            },
+            locale,
+            locales
           }
         ); // call init-client middleware
 
@@ -1398,7 +1408,7 @@
          * @param {string} asPath the URL as shown in browser (virtual path); used for dynamic routes
          */
 
-        getDataHref(href, asPath, ssg) {
+        getDataHref(href, asPath, ssg, locale) {
           var { pathname: hrefPathname, query, search } = (0,
           _parseRelativeUrl.parseRelativeUrl)(href);
           var { pathname: asPathname } = (0,
@@ -1406,7 +1416,10 @@
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug = path => {
-            var dataRoute = (0, _getAssetPathFromRoute.default)(path, ".json");
+            var dataRoute = (0, _router.addLocale)(
+              (0, _getAssetPathFromRoute.default)(path, ".json"),
+              locale
+            );
             return (0, _router.addBasePath)(
               "/_next/data/"
                 .concat(this.buildId)
Diff for main-7f74095..c7a3b6f9a.js
@@ -352,7 +352,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         runtimeConfig = data.runtimeConfig,
         dynamicIds = data.dynamicIds,
         isFallback = data.isFallback,
-        initialHeadData = data.head;
+        initialHeadData = data.head,
+        locales = data.locales;
+      var locale = data.locale;
       var prefix = assetPrefix || ""; // With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time
       // So, this is how we do it in the client side at runtime
 
@@ -369,6 +371,12 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         asPath = (0, _router.delBasePath)(asPath);
       }
 
+      asPath = (0, _router.delLocale)(asPath, locale);
+
+      if (false) {
+        var localePathResult, _require, normalizeLocalePath;
+      }
+
       var pageLoader = new _pageLoader["default"](buildId, prefix, page);
 
       var register = function register(_ref) {
@@ -493,7 +501,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               if (true) {
                 return this.props.children;
               } else {
-                var _require, ReactDevOverlay;
+                var _require2, ReactDevOverlay;
               }
             }
           }
@@ -514,9 +522,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               mod,
               initialErr,
               _yield$pageLoader$loa2,
-              _require2,
-              isValidElementType,
               _require3,
+              isValidElementType,
+              _require4,
               getNodeError,
               renderCtx,
               _args = arguments;
@@ -593,14 +601,14 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
                         break;
                       }
 
-                      (_require2 = __webpack_require__(
+                      (_require3 = __webpack_require__(
                         !(function webpackMissingModule() {
                           var e = new Error("Cannot find module 'react-is'");
                           e.code = "MODULE_NOT_FOUND";
                           throw e;
                         })()
                       )),
-                        (isValidElementType = _require2.isValidElementType);
+                        (isValidElementType = _require3.isValidElementType);
 
                       if (isValidElementType(CachedComponent)) {
                         _context.next = 21;
@@ -662,7 +670,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
                               props: props,
                               err: err
                             });
-                          }
+                          },
+                          locale: locale,
+                          locales: locales
                         }
                       ); // call init-client middleware
 
@@ -1753,7 +1763,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           },
           {
             key: "getDataHref",
-            value: function getDataHref(href, asPath, ssg) {
+            value: function getDataHref(href, asPath, ssg, locale) {
               var _this2 = this;
 
               var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
@@ -1767,9 +1777,9 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               var route = normalizeRoute(hrefPathname);
 
               var getHrefForSlug = function getHrefForSlug(path) {
-                var dataRoute = (0, _getAssetPathFromRoute["default"])(
-                  path,
-                  ".json"
+                var dataRoute = (0, _router.addLocale)(
+                  (0, _getAssetPathFromRoute["default"])(path, ".json"),
+                  locale
                 );
                 return (0, _router.addBasePath)(
                   "/_next/data/"
Diff for index.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      href="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -85,13 +85,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-7f740958d0cc7a3b6f9a.js"
+      src="/_next/static/chunks/main-f6e906adc67b584d1ee1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      src="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4a47cb7dd0a29df91531.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      href="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-cb038f0ac2e648ce4861.module.js"
+      href="/_next/static/chunks/pages/link-776abc716b587eb0f923.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -90,13 +90,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-7f740958d0cc7a3b6f9a.js"
+      src="/_next/static/chunks/main-f6e906adc67b584d1ee1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      src="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -126,13 +126,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4a47cb7dd0a29df91531.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -150,13 +150,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-32658e75d53af2daa2e0.js"
+      src="/_next/static/chunks/pages/link-943a64e08fa49f0674ac.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-cb038f0ac2e648ce4861.module.js"
+      src="/_next/static/chunks/pages/link-776abc716b587eb0f923.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <noscript data-n-css="true"></noscript>
     <link
       rel="preload"
-      href="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      href="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -85,13 +85,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-7f740958d0cc7a3b6f9a.js"
+      src="/_next/static/chunks/main-f6e906adc67b584d1ee1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-1638ee97dc3a5972faa9.module.js"
+      src="/_next/static/chunks/main-c1b72c5de8cb5f24ab66.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -121,13 +121,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2730f3273c05fa35cac6.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4a47cb7dd0a29df91531.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ed82f38c7a1994b728aa.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.057c8f680371688afd9d.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
buildDuration 16s 15.7s -264ms
nodeModulesSize 63.2 MB 63.3 MB ⚠️ +134 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..9339.js gzip 10.9 kB N/A N/A
framework.HASH.js gzip 39 kB 39 kB
main-d493e7d..42f5.js gzip 7.17 kB N/A N/A
webpack-e067..f178.js gzip 751 B 751 B
677f882d2ed8..977d.js gzip N/A 11 kB N/A
main-77437a1..b2c8.js gzip N/A 7.21 kB N/A
Overall change 57.8 kB 58 kB ⚠️ +167 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
677f882d2ed8..dule.js gzip 6.77 kB N/A N/A
framework.HA..dule.js gzip 39 kB 39 kB
main-f8905d4..dule.js gzip 6.24 kB N/A N/A
webpack-07c5..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.87 kB N/A
main-9ca6a23..dule.js gzip N/A 6.28 kB N/A
Overall change 52.7 kB 52.9 kB ⚠️ +146 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/i18n Change
polyfills-4b..e242.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-9a0b9e1..b37e.js gzip 1.28 kB 1.28 kB
_error-ed1b0..8fbd.js gzip 3.44 kB 3.44 kB
hooks-89731c..c609.js gzip 887 B 887 B
index-17468f..5d83.js gzip 227 B 227 B
link-d2344ce..8b36.js gzip 1.3 kB N/A N/A
routerDirect..924c.js gzip 284 B 284 B
withRouter-7..c13d.js gzip 284 B 284 B
link-537beac..0f9a.js gzip N/A 1.32 kB N/A
Overall change 7.71 kB 7.72 kB ⚠️ +12 B
Client Pages Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_app-75d3a82..dule.js gzip 625 B 625 B
_error-4469a..dule.js gzip 2.29 kB 2.29 kB
hooks-cbf13f..dule.js gzip 387 B 387 B
index-b9a643..dule.js gzip 226 B 226 B
link-f8c0daf..dule.js gzip 1.26 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-f..dule.js gzip 282 B 282 B
link-02f45f5..dule.js gzip N/A 1.28 kB N/A
Overall change 5.36 kB 5.37 kB ⚠️ +13 B
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_buildManifest.js gzip 322 B 323 B ⚠️ +1 B
_buildManife..dule.js gzip 329 B 330 B ⚠️ +1 B
Overall change 651 B 653 B ⚠️ +2 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/i18n Change
_error.js 1.05 MB 1.05 MB ⚠️ +806 B
404.html 4.34 kB 4.34 kB
hooks.html 3.92 kB 3.92 kB
index.js 1.05 MB 1.05 MB ⚠️ +806 B
link.js 1.1 MB 1.1 MB ⚠️ +1.42 kB
routerDirect.js 1.09 MB 1.09 MB ⚠️ +1.37 kB
withRouter.js 1.09 MB 1.09 MB ⚠️ +1.37 kB
Overall change 5.4 MB 5.4 MB ⚠️ +5.77 kB
Commit: 5a7e29a

kodiakhq bot pushed a commit that referenced this pull request Oct 12, 2020
While working on #17755 noticed a couple of cases that needed fixing and broke them out to this PR to make that one easier to review. One fix is for `ssgCacheKey` where it wasn't having the `locale` prefix stripped correctly due to the locales no longer being populated under the server instances `renderOpts` and the second fix is for the `asPath` not being set to `/` when the `locale` is the only part in the URL e.g. `/en` became an empty string `""`

x-ref: #17370
kodiakhq bot pushed a commit that referenced this pull request Oct 14, 2020
…17883)

This updates to set the `NEXT_LOCALE` cookie to the default locale when the user prefers a different locale from the default in their `accept-language` header but visits the default locale path e.g. `/en-US` with a `accept-language` preferred header of `nl` will set the `NEXT_LOCALE=en-US` header and then redirect to `/`

x-ref: #17370
kodiakhq bot pushed a commit that referenced this pull request Oct 15, 2020
This adds the `locale` prop for `next/link` to allow transitioning between locales client-side and also allows passing the locale to `router.push/replace` via the transition options similar to `shallow` e.g. `router.push('/another', '/another, { locale: 'nl' })`

x-ref: #17370
kodiakhq bot pushed a commit that referenced this pull request Oct 15, 2020
This adds the i18n config items to the routes-manifest so that they can accessed in the builder. This doesn't increment the routes-manifest version as existing value shapes haven't been modified and an additional non-breaking value is being added

x-ref: #17370
kodiakhq bot pushed a commit that referenced this pull request Oct 16, 2020
This makes sure the correct `initialRevalidateSeconds` field is populated in the `prerender-manifest` for non-dynamic SSG pages since they will be inserted into the `initialPageRevalidationMap` under their locale prefixed variant with `i18n` enabled

x-ref: #17370
kodiakhq bot pushed a commit that referenced this pull request Oct 20, 2020
This makes sure that we detect the correct default locale for domain specific locales since a domain can have a different default locale residing at the root and we need to check this on the client for prerendered/auto-static pages. This also makes sure we disable the built-in redirect handling when on Vercel since it's handled already. 

Tests for this are tricky since we need to load the browser with a custom domain which requires editing the host file. Existing tests should ensure this doesn't break non-domain specific locale behavior though. This was also tested manually while testing vercel/vercel#5298



x-ref: #17370
kodiakhq bot pushed a commit that referenced this pull request Oct 21, 2020
This makes sure the `locales` are passed to `getStaticPaths` and also disables the removing the default locale from the path when the default locale is the preferred header. It also updates tests to ensure the domain redirects are working as expected.  

x-ref: #17370
kodiakhq bot pushed a commit that referenced this pull request Oct 27, 2020
This is a follow-up to #18067 adding an example for i18n routing

x-ref: #17370
@vercel vercel locked as resolved and limited conversation to collaborators Jan 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants