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 handling for dynamic route href resolving and rewrites on the client #15231

Merged
merged 33 commits into from
Aug 13, 2020

Conversation

ijjk
Copy link
Member

@ijjk ijjk commented Jul 16, 2020

This adds initial handling for rewrites on the client to allow rewriting to fallback dynamic SSG pages and auto-exported dynamic pages. Before this if you rewrote to a static dynamic page we would fail to parse the params for the page which would cause the request for the SSG page data to fail since we didn't have the params to interpolate them.

This PR adds looping over the rewrites when a client-side navigation is occurring to resolve the correct as value and parse the params.

TODO:

  • dead-code eliminate client-side rewrites code when rewrites aren't used
  • add additional tests to make sure fallback data is fetched correctly for rewritten dynamic SSG pages
  • add additional tests to ensure dynamic route href resolving is working for prefetching (GSP/GSSP) and transitions
  • investigate whether we need public files to break rewrites chain correctly to match server side rewrites handling

x-ref: #14695

@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 ijjk added create-next-app Related to our CLI tool for quickly starting a new Next.js application. type: documentation examples Issue/PR related to examples labels Jul 30, 2020
Fix _routesManifest loading in modern mode

Add initial handling for rewrites on the client
@ijjk

This comment has been minimized.

@ijjk ijjk force-pushed the add/client-rewrite-handling branch from 4eec9e4 to 31750b7 Compare July 30, 2020 20:01
@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

This comment has been minimized.

@ijjk

This comment has been minimized.

@ijjk ijjk changed the title Add initial handling for rewrites on the client Add initial handling for dynamic route href resolving and rewrites on the client Aug 7, 2020
@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 Aug 12, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 12.3s 12.6s ⚠️ +339ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.7 kB
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
/ failed reqs 0 0
/ total time (seconds) 2.175 2.167 -0.01
/ avg req/sec 1149.26 1153.61 +4.35
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.216 1.2 -0.02
/error-in-render avg req/sec 2056.29 2083.18 +26.89
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..6aa6.js gzip 10 kB 10.4 kB ⚠️ +375 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-9a7a5f4..661e.js gzip 6.71 kB 6.74 kB ⚠️ +22 B
webpack-ccf5..276a.js gzip 751 B 751 B
Overall change 56.6 kB 57 kB ⚠️ +397 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB 6.21 kB ⚠️ +289 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-d0ac695..dule.js gzip 5.79 kB 5.81 kB ⚠️ +21 B
webpack-10c7..dule.js gzip 751 B 751 B
Overall change 51.6 kB 51.9 kB ⚠️ +310 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 322 B ⚠️ +49 B
_buildManife..dule.js gzip 279 B 330 B ⚠️ +51 B
Overall change 552 B 652 B ⚠️ +100 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
index.html gzip 945 B 945 B
link.html gzip 954 B 953 B -1 B
withRouter.html gzip 939 B 938 B -1 B
Overall change 2.84 kB 2.84 kB -2 B

Diffs

Diff for _buildManifest.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": ["static\u002Fchunks\u002Fpages\u002Findex-283eed3c1520dcc26e8d.js"],
   "/_error": [
     "static\u002Fchunks\u002Fpages\u002F_error-deefd9533fb3f2325f40.js"
@@ -12,6 +13,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-9af1d72bd996729e701e.js"
+  ],
+  __sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for _buildManifest.module.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": [
     "static\u002Fchunks\u002Fpages\u002Findex-dc79232991b9d18c3260.module.js"
   ],
@@ -16,6 +17,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-654e4c0aa8f6a4177d77.module.js"
+  ],
+  __sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for 677f882d2ed8..29ff1dba4.js
@@ -363,6 +363,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -672,6 +679,80 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
+      function _createForOfIteratorHelper(o, allowArrayLike) {
+        var it;
+        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
+          if (
+            Array.isArray(o) ||
+            (it = _unsupportedIterableToArray(o)) ||
+            (allowArrayLike && o && typeof o.length === "number")
+          ) {
+            if (it) o = it;
+            var i = 0;
+            var F = function F() {};
+            return {
+              s: F,
+              n: function n() {
+                if (i >= o.length) return { done: true };
+                return { done: false, value: o[i++] };
+              },
+              e: function e(_e) {
+                throw _e;
+              },
+              f: F
+            };
+          }
+          throw new TypeError(
+            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+          );
+        }
+        var normalCompletion = true,
+          didErr = false,
+          err;
+        return {
+          s: function s() {
+            it = o[Symbol.iterator]();
+          },
+          n: function n() {
+            var step = it.next();
+            normalCompletion = step.done;
+            return step;
+          },
+          e: function e(_e2) {
+            didErr = true;
+            err = _e2;
+          },
+          f: function f() {
+            try {
+              if (!normalCompletion && it["return"] != null) it["return"]();
+            } finally {
+              if (didErr) throw err;
+            }
+          }
+        };
+      }
+
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(o);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) {
+          arr2[i] = arr[i];
+        }
+        return arr2;
+      }
+
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -695,6 +776,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -1111,13 +1198,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   options
                 ) {
                   var cleanedAs,
+                    pages,
+                    _yield$this$pageLoade,
+                    rewrites,
                     parsed,
+                    _parsed,
                     pathname,
                     searchParams,
                     query,
                     route,
                     _options$shallow,
                     shallow,
+                    resolvedAs,
                     _ref3,
                     asPathname,
                     routeRegex,
@@ -1168,7 +1260,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             }
 
                             this.asPath = cleanedAs;
-                            Router.events.emit("hashChangeStart", as);
+                            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
                             this.changeState(method, url, as, options);
                             this.scrollToHash(cleanedAs);
                             this.notify(this.components[this.route]);
@@ -1176,18 +1269,37 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context.abrupt("return", true);
 
                           case 16:
+                            _context.next = 18;
+                            return this.pageLoader.getPageList();
+
+                          case 18:
+                            pages = _context.sent;
+                            _context.next = 21;
+                            return this.pageLoader.promisedBuildManifest;
+
+                          case 21:
+                            _yield$this$pageLoade = _context.sent;
+                            rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = tryParseRelativeUrl(url);
 
                             if (parsed) {
-                              _context.next = 19;
+                              _context.next = 26;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 19:
-                            (pathname = parsed.pathname),
-                              (searchParams = parsed.searchParams);
+                          case 26:
+                            (_parsed = parsed),
+                              (pathname = _parsed.pathname),
+                              (searchParams = _parsed.searchParams);
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            }
+
                             query = (0, _querystring.searchParamsToUrlQuery)(
                               searchParams
                             ); // url and as should always be prefixed with basePath by this
@@ -1217,15 +1329,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               (shallow =
                                 _options$shallow === void 0
                                   ? false
-                                  : _options$shallow);
+                                  : _options$shallow); // we need to resolve the as value using rewrites for dynamic SSG
+                            // pages to allow building the data URL correctly
+
+                            resolvedAs = as;
+
+                            if (false) {
+                            }
+
+                            resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 37;
+                              _context.next = 49;
                               break;
                             }
 
                             (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                              cleanedAs
+                              resolvedAs
                             )),
                               (asPathname = _ref3.pathname);
                             routeRegex = (0, _routeRegex.getRouteRegex)(route);
@@ -1234,7 +1354,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             )(asPathname);
 
                             if (routeMatch) {
-                              _context.next = 36;
+                              _context.next = 48;
                               break;
                             }
 
@@ -1245,7 +1365,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 34;
+                              _context.next = 46;
                               break;
                             }
 
@@ -1262,18 +1382,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                             );
 
-                          case 34:
-                            _context.next = 37;
+                          case 46:
+                            _context.next = 49;
                             break;
 
-                          case 36:
+                          case 48:
                             // Merge params into `query`, overwriting any specified in search
                             Object.assign(query, routeMatch);
 
-                          case 37:
+                          case 49:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 38;
-                            _context.next = 41;
+                            _context.prev = 50;
+                            _context.next = 53;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1282,7 +1402,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 41:
+                          case 53:
                             routeInfo = _context.sent;
                             error = routeInfo.error;
                             Router.events.emit("beforeHistoryChange", as);
@@ -1291,7 +1411,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            _context.next = 48;
+                            _context.next = 60;
                             return this.set(
                               route,
                               pathname,
@@ -1300,9 +1420,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               routeInfo
                             );
 
-                          case 48:
+                          case 60:
                             if (!error) {
-                              _context.next = 51;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1313,28 +1433,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 51:
+                          case 63:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 56:
-                            _context.prev = 56;
-                            _context.t0 = _context["catch"](38);
+                          case 68:
+                            _context.prev = 68;
+                            _context.t0 = _context["catch"](50);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 60;
+                              _context.next = 72;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 60:
+                          case 72:
                             throw _context.t0;
 
-                          case 61:
+                          case 73:
                           case "end":
                             return _context.stop();
                         }
@@ -1342,7 +1462,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[38, 56]]
+                    [[50, 68]]
                   );
                 })
               );
@@ -1760,6 +1880,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             value: function urlIsNew(asPath) {
               return this.asPath !== asPath;
             }
+          },
+          {
+            key: "_resolveHref",
+            value: function _resolveHref(parsedHref, pages) {
+              var pathname = parsedHref.pathname;
+              var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+                delBasePath(pathname)
+              );
+
+              if (cleanPathname === "/404" || cleanPathname === "/_error") {
+                return parsedHref;
+              } // handle resolving href for dynamic routes
+
+              if (!pages.includes(cleanPathname)) {
+                var _iterator = _createForOfIteratorHelper(pages),
+                  _step;
+
+                try {
+                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
+                    var page = _step.value;
+
+                    if (
+                      (0, _isDynamic.isDynamicRoute)(page) &&
+                      (0, _routeRegex.getRouteRegex)(page).re.test(
+                        cleanPathname
+                      )
+                    ) {
+                      parsedHref.pathname = addBasePath(page);
+                      break;
+                    }
+                  }
+                } catch (err) {
+                  _iterator.e(err);
+                } finally {
+                  _iterator.f();
+                }
+              }
+
+              return parsedHref;
+            }
             /**
              * Prefetch page code, you may wait for the data during page rendering.
              * This feature only works in production!
@@ -1775,9 +1935,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var asPath,
                     options,
                     parsed,
+                    _parsed2,
                     pathname,
+                    pages,
                     route,
                     _args4 = arguments;
+
                   return _regeneratorRuntime.wrap(
                     function _callee4$(_context4) {
                       while (1) {
@@ -1801,21 +1964,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context4.abrupt("return");
 
                           case 5:
-                            pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                            (_parsed2 = parsed), (pathname = _parsed2.pathname);
+                            _context4.next = 8;
+                            return this.pageLoader.getPageList();
+
+                          case 8:
+                            pages = _context4.sent;
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                             if (true) {
-                              _context4.next = 8;
+                              _context4.next = 13;
                               break;
                             }
 
                             return _context4.abrupt("return");
 
-                          case 8:
+                          case 13:
                             route = (0,
                             _normalizeTrailingSlash.removePathTrailingSlash)(
                               pathname
                             );
-                            _context4.next = 11;
+                            _context4.next = 16;
                             return Promise.all([
                               this.pageLoader.prefetchData(url, asPath),
                               this.pageLoader[
@@ -1823,7 +1997,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               ](route)
                             ]);
 
-                          case 11:
+                          case 16:
                           case "end":
                             return _context4.stop();
                         }
@@ -1925,9 +2099,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var err = new Error("Loading initial props cancelled");
-                  err.cancelled = true;
-                  throw err;
+                  var _err = new Error("Loading initial props cancelled");
+
+                  _err.cancelled = true;
+                  throw _err;
                 }
 
                 return data;
@@ -3465,6 +3640,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
+      /***/
+    },
+
     /***/ wkBT: /***/ function(module, exports) {
       function _nonIterableRest() {
         throw new TypeError(
Diff for 677f882d2ed8..a6.module.js
@@ -329,6 +329,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ TqRt: /***/ function(module, exports) {
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
@@ -554,6 +561,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -955,17 +968,30 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if (!options._h && this.onlyAHashChange(cleanedAs)) {
             this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
             this.changeState(method, url, as, options);
             this.scrollToHash(cleanedAs);
             this.notify(this.components[this.route]);
             Router.events.emit("hashChangeComplete", as);
             return true;
-          }
+          } // The build manifest needs to be loaded before auto-static dynamic pages
+          // get their query parameters to allow ensuring they can be parsed properly
+          // when rewritten to
 
+          var pages = await this.pageLoader.getPageList();
+          var { __rewrites: rewrites } = await this.pageLoader
+            .promisedBuildManifest;
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return false;
           var { pathname, searchParams } = parsed;
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          }
+
           var query = (0, _querystring.searchParamsToUrlQuery)(searchParams); // url and as should always be prefixed with basePath by this
           // point by either next/link or router.push/replace so strip the
           // basePath from the pathname to match the pages dir 1-to-1
@@ -987,11 +1013,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
-          var { shallow = false } = options;
+          var { shallow = false } = options; // we need to resolve the as value using rewrites for dynamic SSG
+          // pages to allow building the data URL correctly
+
+          var resolvedAs = as;
+
+          if (false) {
+          }
+
+          resolvedAs = delBasePath(resolvedAs);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1259,6 +1293,31 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         urlIsNew(asPath) {
           return this.asPath !== asPath;
         }
+
+        _resolveHref(parsedHref, pages) {
+          var { pathname } = parsedHref;
+          var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+            delBasePath(pathname)
+          );
+
+          if (cleanPathname === "/404" || cleanPathname === "/_error") {
+            return parsedHref;
+          } // handle resolving href for dynamic routes
+
+          if (!pages.includes(cleanPathname)) {
+            for (var page of pages) {
+              if (
+                (0, _isDynamic.isDynamicRoute)(page) &&
+                (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+              ) {
+                parsedHref.pathname = addBasePath(page);
+                break;
+              }
+            }
+          }
+
+          return parsedHref;
+        }
         /**
          * Prefetch page code, you may wait for the data during page rendering.
          * This feature only works in production!
@@ -1277,7 +1336,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return;
-          var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+          var { pathname } = parsed;
+          var pages = await this.pageLoader.getPageList();
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
           if (false) {
           }
@@ -1820,6 +1886,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       if (false) {
       }
 
+      /***/
+    },
+
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
       /***/
     }
   }
Diff for main-b2c679a..17.module.js
@@ -1203,17 +1203,15 @@
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(resolve => {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(resolve => {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = () => {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = () => {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(resolve => {
@@ -1225,6 +1223,15 @@
               };
             }
           });
+        }
+
+        getPageList() {
+          if (true) {
+            return this.promisedBuildManifest.then(
+              buildManifest => buildManifest.__sortedPages
+            );
+          } else {
+          }
         } // Returns a promise for the dependencies for a particular route
 
         getDependencies(route) {
Diff for main-d3421a9..998ca3c86.js
@@ -1566,17 +1566,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(function(resolve) {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(function(resolve) {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = function() {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = function() {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(function(resolve) {
@@ -1588,9 +1586,20 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               };
             }
           });
-        } // Returns a promise for the dependencies for a particular route
+        }
 
         _createClass(PageLoader, [
+          {
+            key: "getPageList",
+            value: function getPageList() {
+              if (true) {
+                return this.promisedBuildManifest.then(function(buildManifest) {
+                  return buildManifest.__sortedPages;
+                });
+              } else {
+              }
+            } // Returns a promise for the dependencies for a particular route
+          },
           {
             key: "getDependencies",
             value: function getDependencies(route) {
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-30bd2c0abf69e21f31d9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6e957134ad87644bd4a6.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.5e9fea26cba725fcd040.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-8d27f173b193a86516c1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-30bd2c0abf69e21f31d9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.25e748ff47129ff1dba4.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f3b0cced97bd40dc5910.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6e957134ad87644bd4a6.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.5e9fea26cba725fcd040.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-30bd2c0abf69e21f31d9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6e957134ad87644bd4a6.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.5e9fea26cba725fcd040.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-8d27f173b193a86516c1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-30bd2c0abf69e21f31d9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.25e748ff47129ff1dba4.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f3b0cced97bd40dc5910.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6e957134ad87644bd4a6.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.5e9fea26cba725fcd040.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-30bd2c0abf69e21f31d9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6e957134ad87644bd4a6.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.5e9fea26cba725fcd040.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-8d27f173b193a86516c1.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-30bd2c0abf69e21f31d9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.25e748ff47129ff1dba4.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f3b0cced97bd40dc5910.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6e957134ad87644bd4a6.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.5e9fea26cba725fcd040.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 13.8s 14s ⚠️ +256ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.7 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..6aa6.js gzip 10 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-9a7a5f4..661e.js gzip 6.71 kB N/A N/A
webpack-ccf5..276a.js gzip 751 B 751 B
677f882d2ed8..dac4.js gzip N/A 10.4 kB N/A
main-bc4afd2..44f2.js gzip N/A 6.74 kB N/A
Overall change 56.6 kB 57 kB ⚠️ +397 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-d0ac695..dule.js gzip 5.79 kB N/A N/A
webpack-10c7..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.21 kB N/A
main-8670140..dule.js gzip N/A 5.81 kB N/A
Overall change 51.6 kB 51.9 kB ⚠️ +310 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 322 B ⚠️ +49 B
_buildManife..dule.js gzip 279 B 330 B ⚠️ +51 B
Overall change 552 B 652 B ⚠️ +100 B
Serverless bundles Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_error.js 1.03 MB 1.03 MB -1.26 kB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.03 MB 1.03 MB -1.26 kB
link.js 1.07 MB 1.07 MB -442 B
routerDirect.js 1.06 MB 1.06 MB -442 B
withRouter.js 1.06 MB 1.06 MB -442 B
Overall change 5.26 MB 5.26 MB -3.84 kB
Commit: 0005544

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 14.2s 14s -271ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.7 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
/ failed reqs 0 0
/ total time (seconds) 2.567 2.531 -0.04
/ avg req/sec 973.72 987.57 +13.85
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.541 1.598 ⚠️ +0.06
/error-in-render avg req/sec 1622.83 1564.24 ⚠️ -58.59
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB 10.4 kB ⚠️ +375 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-9a7a5f4..661e.js gzip 6.71 kB 6.74 kB ⚠️ +22 B
webpack-ccf5..276a.js gzip 751 B 751 B
Overall change 56.6 kB 57 kB ⚠️ +397 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB 6.21 kB ⚠️ +289 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-d0ac695..dule.js gzip 5.79 kB 5.8 kB ⚠️ +19 B
webpack-10c7..dule.js gzip 751 B 751 B
Overall change 51.6 kB 51.9 kB ⚠️ +308 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
index.html gzip 947 B 947 B
link.html gzip 954 B 955 B ⚠️ +1 B
withRouter.html gzip 940 B 940 B
Overall change 2.84 kB 2.84 kB ⚠️ +1 B

Diffs

Diff for _buildManifest.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": ["static\u002Fchunks\u002Fpages\u002Findex-283eed3c1520dcc26e8d.js"],
   "/_error": [
     "static\u002Fchunks\u002Fpages\u002F_error-deefd9533fb3f2325f40.js"
@@ -12,6 +13,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-9af1d72bd996729e701e.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for _buildManifest.module.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": [
     "static\u002Fchunks\u002Fpages\u002Findex-dc79232991b9d18c3260.module.js"
   ],
@@ -16,6 +17,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-654e4c0aa8f6a4177d77.module.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for 677f882d2ed8..a6bebf348.js
@@ -363,6 +363,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -671,6 +678,80 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
+      function _createForOfIteratorHelper(o, allowArrayLike) {
+        var it;
+        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
+          if (
+            Array.isArray(o) ||
+            (it = _unsupportedIterableToArray(o)) ||
+            (allowArrayLike && o && typeof o.length === "number")
+          ) {
+            if (it) o = it;
+            var i = 0;
+            var F = function F() {};
+            return {
+              s: F,
+              n: function n() {
+                if (i >= o.length) return { done: true };
+                return { done: false, value: o[i++] };
+              },
+              e: function e(_e) {
+                throw _e;
+              },
+              f: F
+            };
+          }
+          throw new TypeError(
+            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+          );
+        }
+        var normalCompletion = true,
+          didErr = false,
+          err;
+        return {
+          s: function s() {
+            it = o[Symbol.iterator]();
+          },
+          n: function n() {
+            var step = it.next();
+            normalCompletion = step.done;
+            return step;
+          },
+          e: function e(_e2) {
+            didErr = true;
+            err = _e2;
+          },
+          f: function f() {
+            try {
+              if (!normalCompletion && it["return"] != null) it["return"]();
+            } finally {
+              if (didErr) throw err;
+            }
+          }
+        };
+      }
+
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(o);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) {
+          arr2[i] = arr[i];
+        }
+        return arr2;
+      }
+
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -694,6 +775,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -1110,13 +1197,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   options
                 ) {
                   var cleanedAs,
+                    pages,
+                    _yield$this$pageLoade,
+                    rewrites,
                     parsed,
+                    _parsed,
                     pathname,
                     searchParams,
                     query,
                     route,
                     _options$shallow,
                     shallow,
+                    resolvedAs,
                     _ref3,
                     asPathname,
                     routeRegex,
@@ -1167,7 +1259,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             }
 
                             this.asPath = cleanedAs;
-                            Router.events.emit("hashChangeStart", as);
+                            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
                             this.changeState(method, url, as, options);
                             this.scrollToHash(cleanedAs);
                             this.notify(this.components[this.route]);
@@ -1175,18 +1268,37 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context.abrupt("return", true);
 
                           case 16:
+                            _context.next = 18;
+                            return this.pageLoader.getPageList();
+
+                          case 18:
+                            pages = _context.sent;
+                            _context.next = 21;
+                            return this.pageLoader.promisedBuildManifest;
+
+                          case 21:
+                            _yield$this$pageLoade = _context.sent;
+                            rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = tryParseRelativeUrl(url);
 
                             if (parsed) {
-                              _context.next = 19;
+                              _context.next = 26;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 19:
-                            (pathname = parsed.pathname),
-                              (searchParams = parsed.searchParams);
+                          case 26:
+                            (_parsed = parsed),
+                              (pathname = _parsed.pathname),
+                              (searchParams = _parsed.searchParams);
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            }
+
                             query = (0, _querystring.searchParamsToUrlQuery)(
                               searchParams
                             ); // url and as should always be prefixed with basePath by this
@@ -1216,15 +1328,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               (shallow =
                                 _options$shallow === void 0
                                   ? false
-                                  : _options$shallow);
+                                  : _options$shallow); // we need to resolve the as value using rewrites for dynamic SSG
+                            // pages to allow building the data URL correctly
+
+                            resolvedAs = as;
+
+                            if (false) {
+                            }
+
+                            resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 37;
+                              _context.next = 49;
                               break;
                             }
 
                             (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                              cleanedAs
+                              resolvedAs
                             )),
                               (asPathname = _ref3.pathname);
                             routeRegex = (0, _routeRegex.getRouteRegex)(route);
@@ -1233,7 +1353,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             )(asPathname);
 
                             if (routeMatch) {
-                              _context.next = 36;
+                              _context.next = 48;
                               break;
                             }
 
@@ -1244,7 +1364,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 34;
+                              _context.next = 46;
                               break;
                             }
 
@@ -1261,18 +1381,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                             );
 
-                          case 34:
-                            _context.next = 37;
+                          case 46:
+                            _context.next = 49;
                             break;
 
-                          case 36:
+                          case 48:
                             // Merge params into `query`, overwriting any specified in search
                             Object.assign(query, routeMatch);
 
-                          case 37:
+                          case 49:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 38;
-                            _context.next = 41;
+                            _context.prev = 50;
+                            _context.next = 53;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1281,7 +1401,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 41:
+                          case 53:
                             routeInfo = _context.sent;
                             error = routeInfo.error;
                             Router.events.emit("beforeHistoryChange", as);
@@ -1290,7 +1410,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            _context.next = 48;
+                            _context.next = 60;
                             return this.set(
                               route,
                               pathname,
@@ -1299,9 +1419,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               routeInfo
                             );
 
-                          case 48:
+                          case 60:
                             if (!error) {
-                              _context.next = 51;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1312,28 +1432,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 51:
+                          case 63:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 56:
-                            _context.prev = 56;
-                            _context.t0 = _context["catch"](38);
+                          case 68:
+                            _context.prev = 68;
+                            _context.t0 = _context["catch"](50);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 60;
+                              _context.next = 72;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 60:
+                          case 72:
                             throw _context.t0;
 
-                          case 61:
+                          case 73:
                           case "end":
                             return _context.stop();
                         }
@@ -1341,7 +1461,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[38, 56]]
+                    [[50, 68]]
                   );
                 })
               );
@@ -1759,6 +1879,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             value: function urlIsNew(asPath) {
               return this.asPath !== asPath;
             }
+          },
+          {
+            key: "_resolveHref",
+            value: function _resolveHref(parsedHref, pages) {
+              var pathname = parsedHref.pathname;
+              var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+                delBasePath(pathname)
+              );
+
+              if (cleanPathname === "/404" || cleanPathname === "/_error") {
+                return parsedHref;
+              } // handle resolving href for dynamic routes
+
+              if (!pages.includes(cleanPathname)) {
+                var _iterator = _createForOfIteratorHelper(pages),
+                  _step;
+
+                try {
+                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
+                    var page = _step.value;
+
+                    if (
+                      (0, _isDynamic.isDynamicRoute)(page) &&
+                      (0, _routeRegex.getRouteRegex)(page).re.test(
+                        cleanPathname
+                      )
+                    ) {
+                      parsedHref.pathname = addBasePath(page);
+                      break;
+                    }
+                  }
+                } catch (err) {
+                  _iterator.e(err);
+                } finally {
+                  _iterator.f();
+                }
+              }
+
+              return parsedHref;
+            }
             /**
              * Prefetch page code, you may wait for the data during page rendering.
              * This feature only works in production!
@@ -1774,9 +1934,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var asPath,
                     options,
                     parsed,
+                    _parsed2,
                     pathname,
+                    pages,
                     route,
                     _args4 = arguments;
+
                   return _regeneratorRuntime.wrap(
                     function _callee4$(_context4) {
                       while (1) {
@@ -1800,21 +1963,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context4.abrupt("return");
 
                           case 5:
-                            pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                            (_parsed2 = parsed), (pathname = _parsed2.pathname);
+                            _context4.next = 8;
+                            return this.pageLoader.getPageList();
+
+                          case 8:
+                            pages = _context4.sent;
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                             if (true) {
-                              _context4.next = 8;
+                              _context4.next = 13;
                               break;
                             }
 
                             return _context4.abrupt("return");
 
-                          case 8:
+                          case 13:
                             route = (0,
                             _normalizeTrailingSlash.removePathTrailingSlash)(
                               pathname
                             );
-                            _context4.next = 11;
+                            _context4.next = 16;
                             return Promise.all([
                               this.pageLoader.prefetchData(url, asPath),
                               this.pageLoader[
@@ -1822,7 +1996,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               ](route)
                             ]);
 
-                          case 11:
+                          case 16:
                           case "end":
                             return _context4.stop();
                         }
@@ -1924,9 +2098,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var err = new Error("Loading initial props cancelled");
-                  err.cancelled = true;
-                  throw err;
+                  var _err = new Error("Loading initial props cancelled");
+
+                  _err.cancelled = true;
+                  throw _err;
                 }
 
                 return data;
@@ -3462,6 +3637,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
+      /***/
+    },
+
     /***/ wkBT: /***/ function(module, exports) {
       function _nonIterableRest() {
         throw new TypeError(
Diff for 677f882d2ed8..91.module.js
@@ -329,6 +329,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ TqRt: /***/ function(module, exports) {
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
@@ -553,6 +560,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -954,17 +967,30 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if (!options._h && this.onlyAHashChange(cleanedAs)) {
             this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
             this.changeState(method, url, as, options);
             this.scrollToHash(cleanedAs);
             this.notify(this.components[this.route]);
             Router.events.emit("hashChangeComplete", as);
             return true;
-          }
+          } // The build manifest needs to be loaded before auto-static dynamic pages
+          // get their query parameters to allow ensuring they can be parsed properly
+          // when rewritten to
 
+          var pages = await this.pageLoader.getPageList();
+          var { __rewrites: rewrites } = await this.pageLoader
+            .promisedBuildManifest;
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return false;
           var { pathname, searchParams } = parsed;
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          }
+
           var query = (0, _querystring.searchParamsToUrlQuery)(searchParams); // url and as should always be prefixed with basePath by this
           // point by either next/link or router.push/replace so strip the
           // basePath from the pathname to match the pages dir 1-to-1
@@ -986,11 +1012,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
-          var { shallow = false } = options;
+          var { shallow = false } = options; // we need to resolve the as value using rewrites for dynamic SSG
+          // pages to allow building the data URL correctly
+
+          var resolvedAs = as;
+
+          if (false) {
+          }
+
+          resolvedAs = delBasePath(resolvedAs);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1258,6 +1292,31 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         urlIsNew(asPath) {
           return this.asPath !== asPath;
         }
+
+        _resolveHref(parsedHref, pages) {
+          var { pathname } = parsedHref;
+          var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+            delBasePath(pathname)
+          );
+
+          if (cleanPathname === "/404" || cleanPathname === "/_error") {
+            return parsedHref;
+          } // handle resolving href for dynamic routes
+
+          if (!pages.includes(cleanPathname)) {
+            for (var page of pages) {
+              if (
+                (0, _isDynamic.isDynamicRoute)(page) &&
+                (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+              ) {
+                parsedHref.pathname = addBasePath(page);
+                break;
+              }
+            }
+          }
+
+          return parsedHref;
+        }
         /**
          * Prefetch page code, you may wait for the data during page rendering.
          * This feature only works in production!
@@ -1276,7 +1335,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return;
-          var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+          var { pathname } = parsed;
+          var pages = await this.pageLoader.getPageList();
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
           if (false) {
           }
@@ -1817,6 +1883,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       if (false) {
       }
 
+      /***/
+    },
+
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
       /***/
     }
   }
Diff for main-b2c679a..17.module.js
@@ -1203,17 +1203,15 @@
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(resolve => {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(resolve => {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = () => {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = () => {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(resolve => {
@@ -1225,6 +1223,15 @@
               };
             }
           });
+        }
+
+        getPageList() {
+          if (true) {
+            return this.promisedBuildManifest.then(
+              buildManifest => buildManifest.sortedPages
+            );
+          } else {
+          }
         } // Returns a promise for the dependencies for a particular route
 
         getDependencies(route) {
Diff for main-d3421a9..998ca3c86.js
@@ -1566,17 +1566,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(function(resolve) {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(function(resolve) {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = function() {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = function() {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(function(resolve) {
@@ -1588,9 +1586,20 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               };
             }
           });
-        } // Returns a promise for the dependencies for a particular route
+        }
 
         _createClass(PageLoader, [
+          {
+            key: "getPageList",
+            value: function getPageList() {
+              if (true) {
+                return this.promisedBuildManifest.then(function(buildManifest) {
+                  return buildManifest.sortedPages;
+                });
+              } else {
+              }
+            } // Returns a promise for the dependencies for a particular route
+          },
           {
             key: "getDependencies",
             value: function getDependencies(route) {
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-3587001aa510c1b6195b.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-3587001aa510c1b6195b.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-3587001aa510c1b6195b.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 15.6s 16s ⚠️ +435ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.7 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-9a7a5f4..661e.js gzip 6.71 kB N/A N/A
webpack-ccf5..276a.js gzip 751 B 751 B
677f882d2ed8..9a1c.js gzip N/A 10.4 kB N/A
main-3240811..28d3.js gzip N/A 6.74 kB N/A
Overall change 56.6 kB 57 kB ⚠️ +397 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-d0ac695..dule.js gzip 5.79 kB N/A N/A
webpack-10c7..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.21 kB N/A
main-6e8e53c..dule.js gzip N/A 5.8 kB N/A
Overall change 51.6 kB 51.9 kB ⚠️ +308 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Serverless bundles Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_error.js 1.03 MB 1.03 MB -1.26 kB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.03 MB 1.03 MB -1.26 kB
link.js 1.07 MB 1.07 MB -442 B
routerDirect.js 1.06 MB 1.06 MB -442 B
withRouter.js 1.06 MB 1.06 MB -442 B
Overall change 5.26 MB 5.26 MB -3.84 kB
Commit: 6cfadf7

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2020

Failing test suites

Commit: 6cfadf7

test/integration/dynamic-routing/test/index.test.js

  • Dynamic Routing > dev mode > should resolve dynamic route href for page added later
  • Dynamic Routing > production mode > should output a routes-manifest correctly
  • Dynamic Routing > serverless mode > should output a routes-manifest correctly
Expand output

● Dynamic Routing › dev mode › should resolve dynamic route href for page added later

TIMED OUT: success

undefined

  377 | 
  378 |   if (hardError) {
> 379 |     throw new Error('TIMED OUT: ' + regex + '\n\n' + content)
      |           ^
  380 |   }
  381 |   return false
  382 | }

  at check (lib/next-test-utils.js:379:11)
  at Object.<anonymous> (integration/dynamic-routing/test/index.test.js:581:7)

● Dynamic Routing › production mode › should output a routes-manifest correctly

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 8

@@ -42,10 +42,18 @@
        },
      },
    ],
    "dynamicRoutes": Array [
      Object {
+       "namedRegex": "^/added\\-later/(?<slug>[^/]+?)(?:/)?$",
+       "page": "/added-later/[slug]",
+       "regex": "^\\/added\\-later\\/([^\\/]+?)(?:\\/)?$",
+       "routeKeys": Object {
+         "slug": "slug",
+       },
+     },
+     Object {
        "namedRegex": "^/b/(?<a>[^/]+?)(?:/)?$",
        "page": "/b/[123]",
        "regex": "^\\/b\\/([^\\/]+?)(?:\\/)?$",
        "routeKeys": Object {
          "a": "123",

  649 |       }
  650 | 
> 651 |       expect(manifest).toEqual({
      |                        ^
  652 |         version: 3,
  653 |         pages404: true,
  654 |         basePath: '',

  at Object.<anonymous> (integration/dynamic-routing/test/index.test.js:651:24)

● Dynamic Routing › serverless mode › should output a routes-manifest correctly

expect(received).toEqual(expected) // deep equality

- Expected  - 0
+ Received  + 8

@@ -42,10 +42,18 @@
        },
      },
    ],
    "dynamicRoutes": Array [
      Object {
+       "namedRegex": "^/added\\-later/(?<slug>[^/]+?)(?:/)?$",
+       "page": "/added-later/[slug]",
+       "regex": "^\\/added\\-later\\/([^\\/]+?)(?:\\/)?$",
+       "routeKeys": Object {
+         "slug": "slug",
+       },
+     },
+     Object {
        "namedRegex": "^/b/(?<a>[^/]+?)(?:/)?$",
        "page": "/b/[123]",
        "regex": "^\\/b\\/([^\\/]+?)(?:\\/)?$",
        "routeKeys": Object {
          "a": "123",

  649 |       }
  650 | 
> 651 |       expect(manifest).toEqual({
      |                        ^
  652 |         version: 3,
  653 |         pages404: true,
  654 |         basePath: '',

  at Object.<anonymous> (integration/dynamic-routing/test/index.test.js:651:24)

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 13.9s 13.8s -40ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.7 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
/ failed reqs 0 0
/ total time (seconds) 2.55 2.531 -0.02
/ avg req/sec 980.56 987.72 +7.16
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.485 1.538 ⚠️ +0.05
/error-in-render avg req/sec 1683.69 1625.85 ⚠️ -57.84
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB 10.4 kB ⚠️ +375 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-9a7a5f4..661e.js gzip 6.71 kB 6.74 kB ⚠️ +22 B
webpack-ccf5..276a.js gzip 751 B 751 B
Overall change 56.6 kB 57 kB ⚠️ +397 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB 6.21 kB ⚠️ +289 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-d0ac695..dule.js gzip 5.79 kB 5.8 kB ⚠️ +19 B
webpack-10c7..dule.js gzip 751 B 751 B
Overall change 51.6 kB 51.9 kB ⚠️ +308 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
index.html gzip 947 B 947 B
link.html gzip 954 B 955 B ⚠️ +1 B
withRouter.html gzip 940 B 940 B
Overall change 2.84 kB 2.84 kB ⚠️ +1 B

Diffs

Diff for _buildManifest.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": ["static\u002Fchunks\u002Fpages\u002Findex-283eed3c1520dcc26e8d.js"],
   "/_error": [
     "static\u002Fchunks\u002Fpages\u002F_error-deefd9533fb3f2325f40.js"
@@ -12,6 +13,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-9af1d72bd996729e701e.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for _buildManifest.module.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": [
     "static\u002Fchunks\u002Fpages\u002Findex-dc79232991b9d18c3260.module.js"
   ],
@@ -16,6 +17,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-654e4c0aa8f6a4177d77.module.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for 677f882d2ed8..a6bebf348.js
@@ -363,6 +363,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -671,6 +678,80 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
+      function _createForOfIteratorHelper(o, allowArrayLike) {
+        var it;
+        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
+          if (
+            Array.isArray(o) ||
+            (it = _unsupportedIterableToArray(o)) ||
+            (allowArrayLike && o && typeof o.length === "number")
+          ) {
+            if (it) o = it;
+            var i = 0;
+            var F = function F() {};
+            return {
+              s: F,
+              n: function n() {
+                if (i >= o.length) return { done: true };
+                return { done: false, value: o[i++] };
+              },
+              e: function e(_e) {
+                throw _e;
+              },
+              f: F
+            };
+          }
+          throw new TypeError(
+            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+          );
+        }
+        var normalCompletion = true,
+          didErr = false,
+          err;
+        return {
+          s: function s() {
+            it = o[Symbol.iterator]();
+          },
+          n: function n() {
+            var step = it.next();
+            normalCompletion = step.done;
+            return step;
+          },
+          e: function e(_e2) {
+            didErr = true;
+            err = _e2;
+          },
+          f: function f() {
+            try {
+              if (!normalCompletion && it["return"] != null) it["return"]();
+            } finally {
+              if (didErr) throw err;
+            }
+          }
+        };
+      }
+
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(o);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) {
+          arr2[i] = arr[i];
+        }
+        return arr2;
+      }
+
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -694,6 +775,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -1110,13 +1197,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   options
                 ) {
                   var cleanedAs,
+                    pages,
+                    _yield$this$pageLoade,
+                    rewrites,
                     parsed,
+                    _parsed,
                     pathname,
                     searchParams,
                     query,
                     route,
                     _options$shallow,
                     shallow,
+                    resolvedAs,
                     _ref3,
                     asPathname,
                     routeRegex,
@@ -1167,7 +1259,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             }
 
                             this.asPath = cleanedAs;
-                            Router.events.emit("hashChangeStart", as);
+                            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
                             this.changeState(method, url, as, options);
                             this.scrollToHash(cleanedAs);
                             this.notify(this.components[this.route]);
@@ -1175,18 +1268,37 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context.abrupt("return", true);
 
                           case 16:
+                            _context.next = 18;
+                            return this.pageLoader.getPageList();
+
+                          case 18:
+                            pages = _context.sent;
+                            _context.next = 21;
+                            return this.pageLoader.promisedBuildManifest;
+
+                          case 21:
+                            _yield$this$pageLoade = _context.sent;
+                            rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = tryParseRelativeUrl(url);
 
                             if (parsed) {
-                              _context.next = 19;
+                              _context.next = 26;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 19:
-                            (pathname = parsed.pathname),
-                              (searchParams = parsed.searchParams);
+                          case 26:
+                            (_parsed = parsed),
+                              (pathname = _parsed.pathname),
+                              (searchParams = _parsed.searchParams);
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            }
+
                             query = (0, _querystring.searchParamsToUrlQuery)(
                               searchParams
                             ); // url and as should always be prefixed with basePath by this
@@ -1216,15 +1328,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               (shallow =
                                 _options$shallow === void 0
                                   ? false
-                                  : _options$shallow);
+                                  : _options$shallow); // we need to resolve the as value using rewrites for dynamic SSG
+                            // pages to allow building the data URL correctly
+
+                            resolvedAs = as;
+
+                            if (false) {
+                            }
+
+                            resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 37;
+                              _context.next = 49;
                               break;
                             }
 
                             (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                              cleanedAs
+                              resolvedAs
                             )),
                               (asPathname = _ref3.pathname);
                             routeRegex = (0, _routeRegex.getRouteRegex)(route);
@@ -1233,7 +1353,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             )(asPathname);
 
                             if (routeMatch) {
-                              _context.next = 36;
+                              _context.next = 48;
                               break;
                             }
 
@@ -1244,7 +1364,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 34;
+                              _context.next = 46;
                               break;
                             }
 
@@ -1261,18 +1381,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                             );
 
-                          case 34:
-                            _context.next = 37;
+                          case 46:
+                            _context.next = 49;
                             break;
 
-                          case 36:
+                          case 48:
                             // Merge params into `query`, overwriting any specified in search
                             Object.assign(query, routeMatch);
 
-                          case 37:
+                          case 49:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 38;
-                            _context.next = 41;
+                            _context.prev = 50;
+                            _context.next = 53;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1281,7 +1401,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 41:
+                          case 53:
                             routeInfo = _context.sent;
                             error = routeInfo.error;
                             Router.events.emit("beforeHistoryChange", as);
@@ -1290,7 +1410,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            _context.next = 48;
+                            _context.next = 60;
                             return this.set(
                               route,
                               pathname,
@@ -1299,9 +1419,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               routeInfo
                             );
 
-                          case 48:
+                          case 60:
                             if (!error) {
-                              _context.next = 51;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1312,28 +1432,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 51:
+                          case 63:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 56:
-                            _context.prev = 56;
-                            _context.t0 = _context["catch"](38);
+                          case 68:
+                            _context.prev = 68;
+                            _context.t0 = _context["catch"](50);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 60;
+                              _context.next = 72;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 60:
+                          case 72:
                             throw _context.t0;
 
-                          case 61:
+                          case 73:
                           case "end":
                             return _context.stop();
                         }
@@ -1341,7 +1461,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[38, 56]]
+                    [[50, 68]]
                   );
                 })
               );
@@ -1759,6 +1879,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             value: function urlIsNew(asPath) {
               return this.asPath !== asPath;
             }
+          },
+          {
+            key: "_resolveHref",
+            value: function _resolveHref(parsedHref, pages) {
+              var pathname = parsedHref.pathname;
+              var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+                delBasePath(pathname)
+              );
+
+              if (cleanPathname === "/404" || cleanPathname === "/_error") {
+                return parsedHref;
+              } // handle resolving href for dynamic routes
+
+              if (!pages.includes(cleanPathname)) {
+                var _iterator = _createForOfIteratorHelper(pages),
+                  _step;
+
+                try {
+                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
+                    var page = _step.value;
+
+                    if (
+                      (0, _isDynamic.isDynamicRoute)(page) &&
+                      (0, _routeRegex.getRouteRegex)(page).re.test(
+                        cleanPathname
+                      )
+                    ) {
+                      parsedHref.pathname = addBasePath(page);
+                      break;
+                    }
+                  }
+                } catch (err) {
+                  _iterator.e(err);
+                } finally {
+                  _iterator.f();
+                }
+              }
+
+              return parsedHref;
+            }
             /**
              * Prefetch page code, you may wait for the data during page rendering.
              * This feature only works in production!
@@ -1774,9 +1934,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var asPath,
                     options,
                     parsed,
+                    _parsed2,
                     pathname,
+                    pages,
                     route,
                     _args4 = arguments;
+
                   return _regeneratorRuntime.wrap(
                     function _callee4$(_context4) {
                       while (1) {
@@ -1800,21 +1963,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context4.abrupt("return");
 
                           case 5:
-                            pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                            (_parsed2 = parsed), (pathname = _parsed2.pathname);
+                            _context4.next = 8;
+                            return this.pageLoader.getPageList();
+
+                          case 8:
+                            pages = _context4.sent;
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                             if (true) {
-                              _context4.next = 8;
+                              _context4.next = 13;
                               break;
                             }
 
                             return _context4.abrupt("return");
 
-                          case 8:
+                          case 13:
                             route = (0,
                             _normalizeTrailingSlash.removePathTrailingSlash)(
                               pathname
                             );
-                            _context4.next = 11;
+                            _context4.next = 16;
                             return Promise.all([
                               this.pageLoader.prefetchData(url, asPath),
                               this.pageLoader[
@@ -1822,7 +1996,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               ](route)
                             ]);
 
-                          case 11:
+                          case 16:
                           case "end":
                             return _context4.stop();
                         }
@@ -1924,9 +2098,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var err = new Error("Loading initial props cancelled");
-                  err.cancelled = true;
-                  throw err;
+                  var _err = new Error("Loading initial props cancelled");
+
+                  _err.cancelled = true;
+                  throw _err;
                 }
 
                 return data;
@@ -3462,6 +3637,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
+      /***/
+    },
+
     /***/ wkBT: /***/ function(module, exports) {
       function _nonIterableRest() {
         throw new TypeError(
Diff for 677f882d2ed8..91.module.js
@@ -329,6 +329,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ TqRt: /***/ function(module, exports) {
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
@@ -553,6 +560,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -954,17 +967,30 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if (!options._h && this.onlyAHashChange(cleanedAs)) {
             this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
             this.changeState(method, url, as, options);
             this.scrollToHash(cleanedAs);
             this.notify(this.components[this.route]);
             Router.events.emit("hashChangeComplete", as);
             return true;
-          }
+          } // The build manifest needs to be loaded before auto-static dynamic pages
+          // get their query parameters to allow ensuring they can be parsed properly
+          // when rewritten to
 
+          var pages = await this.pageLoader.getPageList();
+          var { __rewrites: rewrites } = await this.pageLoader
+            .promisedBuildManifest;
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return false;
           var { pathname, searchParams } = parsed;
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          }
+
           var query = (0, _querystring.searchParamsToUrlQuery)(searchParams); // url and as should always be prefixed with basePath by this
           // point by either next/link or router.push/replace so strip the
           // basePath from the pathname to match the pages dir 1-to-1
@@ -986,11 +1012,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
-          var { shallow = false } = options;
+          var { shallow = false } = options; // we need to resolve the as value using rewrites for dynamic SSG
+          // pages to allow building the data URL correctly
+
+          var resolvedAs = as;
+
+          if (false) {
+          }
+
+          resolvedAs = delBasePath(resolvedAs);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1258,6 +1292,31 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         urlIsNew(asPath) {
           return this.asPath !== asPath;
         }
+
+        _resolveHref(parsedHref, pages) {
+          var { pathname } = parsedHref;
+          var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+            delBasePath(pathname)
+          );
+
+          if (cleanPathname === "/404" || cleanPathname === "/_error") {
+            return parsedHref;
+          } // handle resolving href for dynamic routes
+
+          if (!pages.includes(cleanPathname)) {
+            for (var page of pages) {
+              if (
+                (0, _isDynamic.isDynamicRoute)(page) &&
+                (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+              ) {
+                parsedHref.pathname = addBasePath(page);
+                break;
+              }
+            }
+          }
+
+          return parsedHref;
+        }
         /**
          * Prefetch page code, you may wait for the data during page rendering.
          * This feature only works in production!
@@ -1276,7 +1335,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return;
-          var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+          var { pathname } = parsed;
+          var pages = await this.pageLoader.getPageList();
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
           if (false) {
           }
@@ -1817,6 +1883,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       if (false) {
       }
 
+      /***/
+    },
+
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
       /***/
     }
   }
Diff for main-b2c679a..17.module.js
@@ -1203,17 +1203,15 @@
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(resolve => {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(resolve => {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = () => {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = () => {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(resolve => {
@@ -1225,6 +1223,15 @@
               };
             }
           });
+        }
+
+        getPageList() {
+          if (true) {
+            return this.promisedBuildManifest.then(
+              buildManifest => buildManifest.sortedPages
+            );
+          } else {
+          }
         } // Returns a promise for the dependencies for a particular route
 
         getDependencies(route) {
Diff for main-d3421a9..998ca3c86.js
@@ -1566,17 +1566,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(function(resolve) {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(function(resolve) {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = function() {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = function() {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(function(resolve) {
@@ -1588,9 +1586,20 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               };
             }
           });
-        } // Returns a promise for the dependencies for a particular route
+        }
 
         _createClass(PageLoader, [
+          {
+            key: "getPageList",
+            value: function getPageList() {
+              if (true) {
+                return this.promisedBuildManifest.then(function(buildManifest) {
+                  return buildManifest.sortedPages;
+                });
+              } else {
+              }
+            } // Returns a promise for the dependencies for a particular route
+          },
           {
             key: "getDependencies",
             value: function getDependencies(route) {
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-3587001aa510c1b6195b.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-3587001aa510c1b6195b.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      href="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-d3421a9581b998ca3c86.js"
+      src="/_next/static/chunks/main-3587001aa510c1b6195b.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-b2c679a983254aeb7617.module.js"
+      src="/_next/static/chunks/main-c8c422424df932ba7ef3.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 15.9s 15.9s ⚠️ +96ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.7 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-9a7a5f4..661e.js gzip 6.71 kB N/A N/A
webpack-ccf5..276a.js gzip 751 B 751 B
677f882d2ed8..9a1c.js gzip N/A 10.4 kB N/A
main-3240811..28d3.js gzip N/A 6.74 kB N/A
Overall change 56.6 kB 57 kB ⚠️ +397 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-d0ac695..dule.js gzip 5.79 kB N/A N/A
webpack-10c7..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.21 kB N/A
main-6e8e53c..dule.js gzip N/A 5.8 kB N/A
Overall change 51.6 kB 51.9 kB ⚠️ +308 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Serverless bundles Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_error.js 1.03 MB 1.03 MB -1.26 kB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.03 MB 1.03 MB -1.26 kB
link.js 1.07 MB 1.07 MB -442 B
routerDirect.js 1.06 MB 1.06 MB -442 B
withRouter.js 1.06 MB 1.06 MB -442 B
Overall change 5.26 MB 5.26 MB -3.84 kB
Commit: 18df786

@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 12.7s 12.4s -358ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.9 kB
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
/ failed reqs 0 0
/ total time (seconds) 2.17 2.134 -0.04
/ avg req/sec 1152.27 1171.66 +19.39
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.266 1.222 -0.04
/error-in-render avg req/sec 1974.17 2045.52 +71.35
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB 10.4 kB ⚠️ +375 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-25aa383..eece.js gzip 6.72 kB 6.74 kB ⚠️ +23 B
webpack-ccf5..276a.js gzip 751 B 751 B
Overall change 56.6 kB 57 kB ⚠️ +398 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB 6.21 kB ⚠️ +289 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-08f768c..dule.js gzip 5.79 kB 5.81 kB ⚠️ +20 B
webpack-10c7..dule.js gzip 751 B 751 B
Overall change 51.6 kB 51.9 kB ⚠️ +309 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
index.html gzip 947 B 948 B ⚠️ +1 B
link.html gzip 955 B 955 B
withRouter.html gzip 939 B 941 B ⚠️ +2 B
Overall change 2.84 kB 2.84 kB ⚠️ +3 B

Diffs

Diff for _buildManifest.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": ["static\u002Fchunks\u002Fpages\u002Findex-283eed3c1520dcc26e8d.js"],
   "/_error": [
     "static\u002Fchunks\u002Fpages\u002F_error-deefd9533fb3f2325f40.js"
@@ -12,6 +13,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-9af1d72bd996729e701e.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for _buildManifest.module.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": [
     "static\u002Fchunks\u002Fpages\u002Findex-dc79232991b9d18c3260.module.js"
   ],
@@ -16,6 +17,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-654e4c0aa8f6a4177d77.module.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for 677f882d2ed8..a6bebf348.js
@@ -363,6 +363,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -671,6 +678,80 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
+      function _createForOfIteratorHelper(o, allowArrayLike) {
+        var it;
+        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
+          if (
+            Array.isArray(o) ||
+            (it = _unsupportedIterableToArray(o)) ||
+            (allowArrayLike && o && typeof o.length === "number")
+          ) {
+            if (it) o = it;
+            var i = 0;
+            var F = function F() {};
+            return {
+              s: F,
+              n: function n() {
+                if (i >= o.length) return { done: true };
+                return { done: false, value: o[i++] };
+              },
+              e: function e(_e) {
+                throw _e;
+              },
+              f: F
+            };
+          }
+          throw new TypeError(
+            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+          );
+        }
+        var normalCompletion = true,
+          didErr = false,
+          err;
+        return {
+          s: function s() {
+            it = o[Symbol.iterator]();
+          },
+          n: function n() {
+            var step = it.next();
+            normalCompletion = step.done;
+            return step;
+          },
+          e: function e(_e2) {
+            didErr = true;
+            err = _e2;
+          },
+          f: function f() {
+            try {
+              if (!normalCompletion && it["return"] != null) it["return"]();
+            } finally {
+              if (didErr) throw err;
+            }
+          }
+        };
+      }
+
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(o);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) {
+          arr2[i] = arr[i];
+        }
+        return arr2;
+      }
+
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -694,6 +775,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -1110,13 +1197,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   options
                 ) {
                   var cleanedAs,
+                    pages,
+                    _yield$this$pageLoade,
+                    rewrites,
                     parsed,
+                    _parsed,
                     pathname,
                     searchParams,
                     query,
                     route,
                     _options$shallow,
                     shallow,
+                    resolvedAs,
                     _ref3,
                     asPathname,
                     routeRegex,
@@ -1167,7 +1259,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             }
 
                             this.asPath = cleanedAs;
-                            Router.events.emit("hashChangeStart", as);
+                            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
                             this.changeState(method, url, as, options);
                             this.scrollToHash(cleanedAs);
                             this.notify(this.components[this.route]);
@@ -1175,18 +1268,37 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context.abrupt("return", true);
 
                           case 16:
+                            _context.next = 18;
+                            return this.pageLoader.getPageList();
+
+                          case 18:
+                            pages = _context.sent;
+                            _context.next = 21;
+                            return this.pageLoader.promisedBuildManifest;
+
+                          case 21:
+                            _yield$this$pageLoade = _context.sent;
+                            rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = tryParseRelativeUrl(url);
 
                             if (parsed) {
-                              _context.next = 19;
+                              _context.next = 26;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 19:
-                            (pathname = parsed.pathname),
-                              (searchParams = parsed.searchParams);
+                          case 26:
+                            (_parsed = parsed),
+                              (pathname = _parsed.pathname),
+                              (searchParams = _parsed.searchParams);
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            }
+
                             query = (0, _querystring.searchParamsToUrlQuery)(
                               searchParams
                             ); // url and as should always be prefixed with basePath by this
@@ -1216,15 +1328,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               (shallow =
                                 _options$shallow === void 0
                                   ? false
-                                  : _options$shallow);
+                                  : _options$shallow); // we need to resolve the as value using rewrites for dynamic SSG
+                            // pages to allow building the data URL correctly
+
+                            resolvedAs = as;
+
+                            if (false) {
+                            }
+
+                            resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 37;
+                              _context.next = 49;
                               break;
                             }
 
                             (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                              cleanedAs
+                              resolvedAs
                             )),
                               (asPathname = _ref3.pathname);
                             routeRegex = (0, _routeRegex.getRouteRegex)(route);
@@ -1233,7 +1353,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             )(asPathname);
 
                             if (routeMatch) {
-                              _context.next = 36;
+                              _context.next = 48;
                               break;
                             }
 
@@ -1244,7 +1364,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 34;
+                              _context.next = 46;
                               break;
                             }
 
@@ -1261,18 +1381,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                             );
 
-                          case 34:
-                            _context.next = 37;
+                          case 46:
+                            _context.next = 49;
                             break;
 
-                          case 36:
+                          case 48:
                             // Merge params into `query`, overwriting any specified in search
                             Object.assign(query, routeMatch);
 
-                          case 37:
+                          case 49:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 38;
-                            _context.next = 41;
+                            _context.prev = 50;
+                            _context.next = 53;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1281,7 +1401,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 41:
+                          case 53:
                             routeInfo = _context.sent;
                             error = routeInfo.error;
                             Router.events.emit("beforeHistoryChange", as);
@@ -1290,7 +1410,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            _context.next = 48;
+                            _context.next = 60;
                             return this.set(
                               route,
                               pathname,
@@ -1299,9 +1419,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               routeInfo
                             );
 
-                          case 48:
+                          case 60:
                             if (!error) {
-                              _context.next = 51;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1312,28 +1432,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 51:
+                          case 63:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 56:
-                            _context.prev = 56;
-                            _context.t0 = _context["catch"](38);
+                          case 68:
+                            _context.prev = 68;
+                            _context.t0 = _context["catch"](50);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 60;
+                              _context.next = 72;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 60:
+                          case 72:
                             throw _context.t0;
 
-                          case 61:
+                          case 73:
                           case "end":
                             return _context.stop();
                         }
@@ -1341,7 +1461,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[38, 56]]
+                    [[50, 68]]
                   );
                 })
               );
@@ -1759,6 +1879,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             value: function urlIsNew(asPath) {
               return this.asPath !== asPath;
             }
+          },
+          {
+            key: "_resolveHref",
+            value: function _resolveHref(parsedHref, pages) {
+              var pathname = parsedHref.pathname;
+              var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+                delBasePath(pathname)
+              );
+
+              if (cleanPathname === "/404" || cleanPathname === "/_error") {
+                return parsedHref;
+              } // handle resolving href for dynamic routes
+
+              if (!pages.includes(cleanPathname)) {
+                var _iterator = _createForOfIteratorHelper(pages),
+                  _step;
+
+                try {
+                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
+                    var page = _step.value;
+
+                    if (
+                      (0, _isDynamic.isDynamicRoute)(page) &&
+                      (0, _routeRegex.getRouteRegex)(page).re.test(
+                        cleanPathname
+                      )
+                    ) {
+                      parsedHref.pathname = addBasePath(page);
+                      break;
+                    }
+                  }
+                } catch (err) {
+                  _iterator.e(err);
+                } finally {
+                  _iterator.f();
+                }
+              }
+
+              return parsedHref;
+            }
             /**
              * Prefetch page code, you may wait for the data during page rendering.
              * This feature only works in production!
@@ -1774,9 +1934,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var asPath,
                     options,
                     parsed,
+                    _parsed2,
                     pathname,
+                    pages,
                     route,
                     _args4 = arguments;
+
                   return _regeneratorRuntime.wrap(
                     function _callee4$(_context4) {
                       while (1) {
@@ -1800,21 +1963,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context4.abrupt("return");
 
                           case 5:
-                            pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                            (_parsed2 = parsed), (pathname = _parsed2.pathname);
+                            _context4.next = 8;
+                            return this.pageLoader.getPageList();
+
+                          case 8:
+                            pages = _context4.sent;
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                             if (true) {
-                              _context4.next = 8;
+                              _context4.next = 13;
                               break;
                             }
 
                             return _context4.abrupt("return");
 
-                          case 8:
+                          case 13:
                             route = (0,
                             _normalizeTrailingSlash.removePathTrailingSlash)(
                               pathname
                             );
-                            _context4.next = 11;
+                            _context4.next = 16;
                             return Promise.all([
                               this.pageLoader.prefetchData(url, asPath),
                               this.pageLoader[
@@ -1822,7 +1996,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               ](route)
                             ]);
 
-                          case 11:
+                          case 16:
                           case "end":
                             return _context4.stop();
                         }
@@ -1924,9 +2098,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var err = new Error("Loading initial props cancelled");
-                  err.cancelled = true;
-                  throw err;
+                  var _err = new Error("Loading initial props cancelled");
+
+                  _err.cancelled = true;
+                  throw _err;
                 }
 
                 return data;
@@ -3462,6 +3637,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
+      /***/
+    },
+
     /***/ wkBT: /***/ function(module, exports) {
       function _nonIterableRest() {
         throw new TypeError(
Diff for 677f882d2ed8..91.module.js
@@ -329,6 +329,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ TqRt: /***/ function(module, exports) {
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
@@ -553,6 +560,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -954,17 +967,30 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if (!options._h && this.onlyAHashChange(cleanedAs)) {
             this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
             this.changeState(method, url, as, options);
             this.scrollToHash(cleanedAs);
             this.notify(this.components[this.route]);
             Router.events.emit("hashChangeComplete", as);
             return true;
-          }
+          } // The build manifest needs to be loaded before auto-static dynamic pages
+          // get their query parameters to allow ensuring they can be parsed properly
+          // when rewritten to
 
+          var pages = await this.pageLoader.getPageList();
+          var { __rewrites: rewrites } = await this.pageLoader
+            .promisedBuildManifest;
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return false;
           var { pathname, searchParams } = parsed;
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          }
+
           var query = (0, _querystring.searchParamsToUrlQuery)(searchParams); // url and as should always be prefixed with basePath by this
           // point by either next/link or router.push/replace so strip the
           // basePath from the pathname to match the pages dir 1-to-1
@@ -986,11 +1012,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
-          var { shallow = false } = options;
+          var { shallow = false } = options; // we need to resolve the as value using rewrites for dynamic SSG
+          // pages to allow building the data URL correctly
+
+          var resolvedAs = as;
+
+          if (false) {
+          }
+
+          resolvedAs = delBasePath(resolvedAs);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1258,6 +1292,31 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         urlIsNew(asPath) {
           return this.asPath !== asPath;
         }
+
+        _resolveHref(parsedHref, pages) {
+          var { pathname } = parsedHref;
+          var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+            delBasePath(pathname)
+          );
+
+          if (cleanPathname === "/404" || cleanPathname === "/_error") {
+            return parsedHref;
+          } // handle resolving href for dynamic routes
+
+          if (!pages.includes(cleanPathname)) {
+            for (var page of pages) {
+              if (
+                (0, _isDynamic.isDynamicRoute)(page) &&
+                (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+              ) {
+                parsedHref.pathname = addBasePath(page);
+                break;
+              }
+            }
+          }
+
+          return parsedHref;
+        }
         /**
          * Prefetch page code, you may wait for the data during page rendering.
          * This feature only works in production!
@@ -1276,7 +1335,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return;
-          var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+          var { pathname } = parsed;
+          var pages = await this.pageLoader.getPageList();
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
           if (false) {
           }
@@ -1817,6 +1883,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       if (false) {
       }
 
+      /***/
+    },
+
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
       /***/
     }
   }
Diff for main-45dd573..12.module.js
@@ -1209,17 +1209,15 @@
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(resolve => {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(resolve => {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = () => {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = () => {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(resolve => {
@@ -1231,6 +1229,15 @@
               };
             }
           });
+        }
+
+        getPageList() {
+          if (true) {
+            return this.promisedBuildManifest.then(
+              buildManifest => buildManifest.sortedPages
+            );
+          } else {
+          }
         } // Returns a promise for the dependencies for a particular route
 
         getDependencies(route) {
Diff for main-a224724..6408a53fd.js
@@ -1572,17 +1572,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(function(resolve) {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(function(resolve) {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = function() {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = function() {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(function(resolve) {
@@ -1594,9 +1592,20 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               };
             }
           });
-        } // Returns a promise for the dependencies for a particular route
+        }
 
         _createClass(PageLoader, [
+          {
+            key: "getPageList",
+            value: function getPageList() {
+              if (true) {
+                return this.promisedBuildManifest.then(function(buildManifest) {
+                  return buildManifest.sortedPages;
+                });
+              } else {
+              }
+            } // Returns a promise for the dependencies for a particular route
+          },
           {
             key: "getDependencies",
             value: function getDependencies(route) {
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      href="/_next/static/chunks/main-8246440b6fcfd05b55d8.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-a22472456fd6408a53fd.js"
+      src="/_next/static/chunks/main-6657a21886ed16a7e6a7.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      src="/_next/static/chunks/main-8246440b6fcfd05b55d8.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      href="/_next/static/chunks/main-8246440b6fcfd05b55d8.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-a22472456fd6408a53fd.js"
+      src="/_next/static/chunks/main-6657a21886ed16a7e6a7.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      src="/_next/static/chunks/main-8246440b6fcfd05b55d8.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      href="/_next/static/chunks/main-8246440b6fcfd05b55d8.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-a22472456fd6408a53fd.js"
+      src="/_next/static/chunks/main-6657a21886ed16a7e6a7.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      src="/_next/static/chunks/main-8246440b6fcfd05b55d8.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 14.6s 14.7s ⚠️ +123ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +19.9 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-25aa383..eece.js gzip 6.72 kB N/A N/A
webpack-ccf5..276a.js gzip 751 B 751 B
677f882d2ed8..9a1c.js gzip N/A 10.4 kB N/A
main-942f63b..66fb.js gzip N/A 6.74 kB N/A
Overall change 56.6 kB 57 kB ⚠️ +398 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-08f768c..dule.js gzip 5.79 kB N/A N/A
webpack-10c7..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.21 kB N/A
main-2739b89..dule.js gzip N/A 5.81 kB N/A
Overall change 51.6 kB 51.9 kB ⚠️ +309 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Serverless bundles Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_error.js 1.03 MB 1.03 MB -1.26 kB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.03 MB 1.03 MB -1.26 kB
link.js 1.07 MB 1.07 MB -442 B
routerDirect.js 1.06 MB 1.06 MB -442 B
withRouter.js 1.06 MB 1.06 MB -442 B
Overall change 5.26 MB 5.26 MB -3.84 kB
Commit: e0337ad

@ijjk ijjk requested a review from Timer August 12, 2020 22:54
@ijjk
Copy link
Member Author

ijjk commented Aug 12, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 13.6s 13.5s -110ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +25.6 kB
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
/ failed reqs 0 0
/ total time (seconds) 2.619 2.616 0
/ avg req/sec 954.73 955.83 +1.1
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.583 1.522 -0.06
/error-in-render avg req/sec 1579.54 1642.15 +62.61
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB 10.4 kB ⚠️ +375 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-25aa383..eece.js gzip 6.72 kB 6.75 kB ⚠️ +30 B
webpack-ccf5..276a.js gzip 751 B 751 B
Overall change 56.6 kB 57 kB ⚠️ +405 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB 6.21 kB ⚠️ +289 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-08f768c..dule.js gzip 5.79 kB 5.82 kB ⚠️ +29 B
webpack-10c7..dule.js gzip 751 B 751 B
Overall change 51.6 kB 51.9 kB ⚠️ +318 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
index.html gzip 947 B 949 B ⚠️ +2 B
link.html gzip 955 B 957 B ⚠️ +2 B
withRouter.html gzip 939 B 942 B ⚠️ +3 B
Overall change 2.84 kB 2.85 kB ⚠️ +7 B

Diffs

Diff for _buildManifest.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": ["static\u002Fchunks\u002Fpages\u002Findex-283eed3c1520dcc26e8d.js"],
   "/_error": [
     "static\u002Fchunks\u002Fpages\u002F_error-deefd9533fb3f2325f40.js"
@@ -12,6 +13,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-9af1d72bd996729e701e.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for _buildManifest.module.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": [
     "static\u002Fchunks\u002Fpages\u002Findex-dc79232991b9d18c3260.module.js"
   ],
@@ -16,6 +17,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-654e4c0aa8f6a4177d77.module.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for 677f882d2ed8..a6bebf348.js
@@ -363,6 +363,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -671,6 +678,80 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
+      function _createForOfIteratorHelper(o, allowArrayLike) {
+        var it;
+        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
+          if (
+            Array.isArray(o) ||
+            (it = _unsupportedIterableToArray(o)) ||
+            (allowArrayLike && o && typeof o.length === "number")
+          ) {
+            if (it) o = it;
+            var i = 0;
+            var F = function F() {};
+            return {
+              s: F,
+              n: function n() {
+                if (i >= o.length) return { done: true };
+                return { done: false, value: o[i++] };
+              },
+              e: function e(_e) {
+                throw _e;
+              },
+              f: F
+            };
+          }
+          throw new TypeError(
+            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+          );
+        }
+        var normalCompletion = true,
+          didErr = false,
+          err;
+        return {
+          s: function s() {
+            it = o[Symbol.iterator]();
+          },
+          n: function n() {
+            var step = it.next();
+            normalCompletion = step.done;
+            return step;
+          },
+          e: function e(_e2) {
+            didErr = true;
+            err = _e2;
+          },
+          f: function f() {
+            try {
+              if (!normalCompletion && it["return"] != null) it["return"]();
+            } finally {
+              if (didErr) throw err;
+            }
+          }
+        };
+      }
+
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(o);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) {
+          arr2[i] = arr[i];
+        }
+        return arr2;
+      }
+
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -694,6 +775,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -1110,13 +1197,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   options
                 ) {
                   var cleanedAs,
+                    pages,
+                    _yield$this$pageLoade,
+                    rewrites,
                     parsed,
+                    _parsed,
                     pathname,
                     searchParams,
                     query,
                     route,
                     _options$shallow,
                     shallow,
+                    resolvedAs,
                     _ref3,
                     asPathname,
                     routeRegex,
@@ -1167,7 +1259,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             }
 
                             this.asPath = cleanedAs;
-                            Router.events.emit("hashChangeStart", as);
+                            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
                             this.changeState(method, url, as, options);
                             this.scrollToHash(cleanedAs);
                             this.notify(this.components[this.route]);
@@ -1175,18 +1268,37 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context.abrupt("return", true);
 
                           case 16:
+                            _context.next = 18;
+                            return this.pageLoader.getPageList();
+
+                          case 18:
+                            pages = _context.sent;
+                            _context.next = 21;
+                            return this.pageLoader.promisedBuildManifest;
+
+                          case 21:
+                            _yield$this$pageLoade = _context.sent;
+                            rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = tryParseRelativeUrl(url);
 
                             if (parsed) {
-                              _context.next = 19;
+                              _context.next = 26;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 19:
-                            (pathname = parsed.pathname),
-                              (searchParams = parsed.searchParams);
+                          case 26:
+                            (_parsed = parsed),
+                              (pathname = _parsed.pathname),
+                              (searchParams = _parsed.searchParams);
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            }
+
                             query = (0, _querystring.searchParamsToUrlQuery)(
                               searchParams
                             ); // url and as should always be prefixed with basePath by this
@@ -1216,15 +1328,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               (shallow =
                                 _options$shallow === void 0
                                   ? false
-                                  : _options$shallow);
+                                  : _options$shallow); // we need to resolve the as value using rewrites for dynamic SSG
+                            // pages to allow building the data URL correctly
+
+                            resolvedAs = as;
+
+                            if (false) {
+                            }
+
+                            resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 37;
+                              _context.next = 49;
                               break;
                             }
 
                             (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                              cleanedAs
+                              resolvedAs
                             )),
                               (asPathname = _ref3.pathname);
                             routeRegex = (0, _routeRegex.getRouteRegex)(route);
@@ -1233,7 +1353,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             )(asPathname);
 
                             if (routeMatch) {
-                              _context.next = 36;
+                              _context.next = 48;
                               break;
                             }
 
@@ -1244,7 +1364,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 34;
+                              _context.next = 46;
                               break;
                             }
 
@@ -1261,18 +1381,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                             );
 
-                          case 34:
-                            _context.next = 37;
+                          case 46:
+                            _context.next = 49;
                             break;
 
-                          case 36:
+                          case 48:
                             // Merge params into `query`, overwriting any specified in search
                             Object.assign(query, routeMatch);
 
-                          case 37:
+                          case 49:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 38;
-                            _context.next = 41;
+                            _context.prev = 50;
+                            _context.next = 53;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1281,7 +1401,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 41:
+                          case 53:
                             routeInfo = _context.sent;
                             error = routeInfo.error;
                             Router.events.emit("beforeHistoryChange", as);
@@ -1290,7 +1410,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            _context.next = 48;
+                            _context.next = 60;
                             return this.set(
                               route,
                               pathname,
@@ -1299,9 +1419,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               routeInfo
                             );
 
-                          case 48:
+                          case 60:
                             if (!error) {
-                              _context.next = 51;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1312,28 +1432,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 51:
+                          case 63:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 56:
-                            _context.prev = 56;
-                            _context.t0 = _context["catch"](38);
+                          case 68:
+                            _context.prev = 68;
+                            _context.t0 = _context["catch"](50);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 60;
+                              _context.next = 72;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 60:
+                          case 72:
                             throw _context.t0;
 
-                          case 61:
+                          case 73:
                           case "end":
                             return _context.stop();
                         }
@@ -1341,7 +1461,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[38, 56]]
+                    [[50, 68]]
                   );
                 })
               );
@@ -1759,6 +1879,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             value: function urlIsNew(asPath) {
               return this.asPath !== asPath;
             }
+          },
+          {
+            key: "_resolveHref",
+            value: function _resolveHref(parsedHref, pages) {
+              var pathname = parsedHref.pathname;
+              var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+                delBasePath(pathname)
+              );
+
+              if (cleanPathname === "/404" || cleanPathname === "/_error") {
+                return parsedHref;
+              } // handle resolving href for dynamic routes
+
+              if (!pages.includes(cleanPathname)) {
+                var _iterator = _createForOfIteratorHelper(pages),
+                  _step;
+
+                try {
+                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
+                    var page = _step.value;
+
+                    if (
+                      (0, _isDynamic.isDynamicRoute)(page) &&
+                      (0, _routeRegex.getRouteRegex)(page).re.test(
+                        cleanPathname
+                      )
+                    ) {
+                      parsedHref.pathname = addBasePath(page);
+                      break;
+                    }
+                  }
+                } catch (err) {
+                  _iterator.e(err);
+                } finally {
+                  _iterator.f();
+                }
+              }
+
+              return parsedHref;
+            }
             /**
              * Prefetch page code, you may wait for the data during page rendering.
              * This feature only works in production!
@@ -1774,9 +1934,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var asPath,
                     options,
                     parsed,
+                    _parsed2,
                     pathname,
+                    pages,
                     route,
                     _args4 = arguments;
+
                   return _regeneratorRuntime.wrap(
                     function _callee4$(_context4) {
                       while (1) {
@@ -1800,21 +1963,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context4.abrupt("return");
 
                           case 5:
-                            pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                            (_parsed2 = parsed), (pathname = _parsed2.pathname);
+                            _context4.next = 8;
+                            return this.pageLoader.getPageList();
+
+                          case 8:
+                            pages = _context4.sent;
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                             if (true) {
-                              _context4.next = 8;
+                              _context4.next = 13;
                               break;
                             }
 
                             return _context4.abrupt("return");
 
-                          case 8:
+                          case 13:
                             route = (0,
                             _normalizeTrailingSlash.removePathTrailingSlash)(
                               pathname
                             );
-                            _context4.next = 11;
+                            _context4.next = 16;
                             return Promise.all([
                               this.pageLoader.prefetchData(url, asPath),
                               this.pageLoader[
@@ -1822,7 +1996,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               ](route)
                             ]);
 
-                          case 11:
+                          case 16:
                           case "end":
                             return _context4.stop();
                         }
@@ -1924,9 +2098,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var err = new Error("Loading initial props cancelled");
-                  err.cancelled = true;
-                  throw err;
+                  var _err = new Error("Loading initial props cancelled");
+
+                  _err.cancelled = true;
+                  throw _err;
                 }
 
                 return data;
@@ -3462,6 +3637,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
+      /***/
+    },
+
     /***/ wkBT: /***/ function(module, exports) {
       function _nonIterableRest() {
         throw new TypeError(
Diff for 677f882d2ed8..91.module.js
@@ -329,6 +329,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ TqRt: /***/ function(module, exports) {
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
@@ -553,6 +560,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _parseRelativeUrl = __webpack_require__("hS4m");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -954,17 +967,30 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if (!options._h && this.onlyAHashChange(cleanedAs)) {
             this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
             this.changeState(method, url, as, options);
             this.scrollToHash(cleanedAs);
             this.notify(this.components[this.route]);
             Router.events.emit("hashChangeComplete", as);
             return true;
-          }
+          } // The build manifest needs to be loaded before auto-static dynamic pages
+          // get their query parameters to allow ensuring they can be parsed properly
+          // when rewritten to
 
+          var pages = await this.pageLoader.getPageList();
+          var { __rewrites: rewrites } = await this.pageLoader
+            .promisedBuildManifest;
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return false;
           var { pathname, searchParams } = parsed;
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          }
+
           var query = (0, _querystring.searchParamsToUrlQuery)(searchParams); // url and as should always be prefixed with basePath by this
           // point by either next/link or router.push/replace so strip the
           // basePath from the pathname to match the pages dir 1-to-1
@@ -986,11 +1012,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
-          var { shallow = false } = options;
+          var { shallow = false } = options; // we need to resolve the as value using rewrites for dynamic SSG
+          // pages to allow building the data URL correctly
+
+          var resolvedAs = as;
+
+          if (false) {
+          }
+
+          resolvedAs = delBasePath(resolvedAs);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1258,6 +1292,31 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         urlIsNew(asPath) {
           return this.asPath !== asPath;
         }
+
+        _resolveHref(parsedHref, pages) {
+          var { pathname } = parsedHref;
+          var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+            delBasePath(pathname)
+          );
+
+          if (cleanPathname === "/404" || cleanPathname === "/_error") {
+            return parsedHref;
+          } // handle resolving href for dynamic routes
+
+          if (!pages.includes(cleanPathname)) {
+            for (var page of pages) {
+              if (
+                (0, _isDynamic.isDynamicRoute)(page) &&
+                (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+              ) {
+                parsedHref.pathname = addBasePath(page);
+                break;
+              }
+            }
+          }
+
+          return parsedHref;
+        }
         /**
          * Prefetch page code, you may wait for the data during page rendering.
          * This feature only works in production!
@@ -1276,7 +1335,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return;
-          var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+          var { pathname } = parsed;
+          var pages = await this.pageLoader.getPageList();
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
           if (false) {
           }
@@ -1817,6 +1883,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       if (false) {
       }
 
+      /***/
+    },
+
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
       /***/
     }
   }
Diff for main-45dd573..12.module.js
@@ -1196,6 +1196,7 @@
           this.loadingRoutes = void 0;
           this.promisedBuildManifest = void 0;
           this.promisedSsgManifest = void 0;
+          this.promisedDevPagesManifest = void 0;
           this.buildId = buildId;
           this.assetPrefix = assetPrefix;
           this.pageCache = {};
@@ -1209,17 +1210,15 @@
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(resolve => {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(resolve => {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = () => {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = () => {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(resolve => {
@@ -1231,6 +1230,15 @@
               };
             }
           });
+        }
+
+        getPageList() {
+          if (true) {
+            return this.promisedBuildManifest.then(
+              buildManifest => buildManifest.sortedPages
+            );
+          } else {
+          }
         } // Returns a promise for the dependencies for a particular route
 
         getDependencies(route) {
Diff for main-a224724..6408a53fd.js
@@ -1559,6 +1559,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           this.loadingRoutes = void 0;
           this.promisedBuildManifest = void 0;
           this.promisedSsgManifest = void 0;
+          this.promisedDevPagesManifest = void 0;
           this.buildId = buildId;
           this.assetPrefix = assetPrefix;
           this.pageCache = {};
@@ -1572,17 +1573,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(function(resolve) {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(function(resolve) {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = function() {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = function() {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(function(resolve) {
@@ -1594,9 +1593,20 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               };
             }
           });
-        } // Returns a promise for the dependencies for a particular route
+        }
 
         _createClass(PageLoader, [
+          {
+            key: "getPageList",
+            value: function getPageList() {
+              if (true) {
+                return this.promisedBuildManifest.then(function(buildManifest) {
+                  return buildManifest.sortedPages;
+                });
+              } else {
+              }
+            } // Returns a promise for the dependencies for a particular route
+          },
           {
             key: "getDependencies",
             value: function getDependencies(route) {
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      href="/_next/static/chunks/main-ca5c70de123b8fe6b59a.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-a22472456fd6408a53fd.js"
+      src="/_next/static/chunks/main-8af8ab82a102203bdb9f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      src="/_next/static/chunks/main-ca5c70de123b8fe6b59a.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      href="/_next/static/chunks/main-ca5c70de123b8fe6b59a.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-a22472456fd6408a53fd.js"
+      src="/_next/static/chunks/main-8af8ab82a102203bdb9f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      src="/_next/static/chunks/main-ca5c70de123b8fe6b59a.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      href="/_next/static/chunks/main-ca5c70de123b8fe6b59a.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-a22472456fd6408a53fd.js"
+      src="/_next/static/chunks/main-8af8ab82a102203bdb9f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-45dd573719aefbc1b512.module.js"
+      src="/_next/static/chunks/main-ca5c70de123b8fe6b59a.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.3d0d08a6a1da6bebf348.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a5b4f37c548e8cab1d8f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e969023da6b448224391.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.665d5419472056ad62c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 15.4s 15.9s ⚠️ +475ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +25.6 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..ee8a.js gzip 10 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-25aa383..eece.js gzip 6.72 kB N/A N/A
webpack-ccf5..276a.js gzip 751 B 751 B
677f882d2ed8..9a1c.js gzip N/A 10.4 kB N/A
main-347f074..f3e9.js gzip N/A 6.75 kB N/A
Overall change 56.6 kB 57 kB ⚠️ +405 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.92 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-08f768c..dule.js gzip 5.79 kB N/A N/A
webpack-10c7..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.21 kB N/A
main-89774b6..dule.js gzip N/A 5.82 kB N/A
Overall change 51.6 kB 51.9 kB ⚠️ +318 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Serverless bundles Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_error.js 1.03 MB 1.03 MB -765 B
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.03 MB 1.03 MB -765 B
link.js 1.07 MB 1.07 MB ⚠️ +52 B
routerDirect.js 1.06 MB 1.06 MB ⚠️ +52 B
withRouter.js 1.06 MB 1.06 MB ⚠️ +52 B
Overall change 5.26 MB 5.26 MB -1.37 kB
Commit: 78068dc

@ijjk
Copy link
Member Author

ijjk commented Aug 13, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 15.2s 13.9s -1.2s
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +25.6 kB
Page Load Tests Overall increase ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
/ failed reqs 0 0
/ total time (seconds) 2.718 2.544 -0.17
/ avg req/sec 919.8 982.87 +63.07
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.66 1.559 -0.1
/error-in-render avg req/sec 1506.43 1603.58 +97.15
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..9460.js gzip 9.93 kB 10.3 kB ⚠️ +372 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-5c21840..49c9.js gzip 6.69 kB 6.72 kB ⚠️ +30 B
webpack-ccf5..276a.js gzip 751 B 751 B
Overall change 56.5 kB 56.9 kB ⚠️ +402 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.84 kB 6.13 kB ⚠️ +283 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-c0c009b..dule.js gzip 5.78 kB 5.81 kB ⚠️ +29 B
webpack-10c7..dule.js gzip 751 B 751 B
Overall change 51.5 kB 51.8 kB ⚠️ +312 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
index.html gzip 949 B 948 B -1 B
link.html gzip 956 B 955 B -1 B
withRouter.html gzip 943 B 941 B -2 B
Overall change 2.85 kB 2.84 kB -4 B

Diffs

Diff for _buildManifest.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": ["static\u002Fchunks\u002Fpages\u002Findex-283eed3c1520dcc26e8d.js"],
   "/_error": [
     "static\u002Fchunks\u002Fpages\u002F_error-deefd9533fb3f2325f40.js"
@@ -12,6 +13,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-9af1d72bd996729e701e.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for _buildManifest.module.js
@@ -1,4 +1,5 @@
 self.__BUILD_MANIFEST = {
+  __rewrites: [],
   "/": [
     "static\u002Fchunks\u002Fpages\u002Findex-dc79232991b9d18c3260.module.js"
   ],
@@ -16,6 +17,15 @@ self.__BUILD_MANIFEST = {
   ],
   "/withRouter": [
     "static\u002Fchunks\u002Fpages\u002FwithRouter-654e4c0aa8f6a4177d77.module.js"
+  ],
+  sortedPages: [
+    "\u002F",
+    "\u002F_app",
+    "\u002F_error",
+    "\u002Fhooks",
+    "\u002Flink",
+    "\u002FrouterDirect",
+    "\u002FwithRouter"
   ]
 };
 self.__BUILD_MANIFEST_CB && self.__BUILD_MANIFEST_CB();
Diff for 677f882d2ed8..16.module.js
@@ -329,6 +329,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ TqRt: /***/ function(module, exports) {
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
@@ -555,6 +562,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
           ? obj
@@ -929,17 +942,30 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if (!options._h && this.onlyAHashChange(cleanedAs)) {
             this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
             this.changeState(method, url, as, options);
             this.scrollToHash(cleanedAs);
             this.notify(this.components[this.route]);
             Router.events.emit("hashChangeComplete", as);
             return true;
-          }
+          } // The build manifest needs to be loaded before auto-static dynamic pages
+          // get their query parameters to allow ensuring they can be parsed properly
+          // when rewritten to
 
+          var pages = await this.pageLoader.getPageList();
+          var { __rewrites: rewrites } = await this.pageLoader
+            .promisedBuildManifest;
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return false;
           var { pathname, searchParams } = parsed;
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          }
+
           var query = (0, _querystring.searchParamsToUrlQuery)(searchParams); // url and as should always be prefixed with basePath by this
           // point by either next/link or router.push/replace so strip the
           // basePath from the pathname to match the pages dir 1-to-1
@@ -961,11 +987,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
-          var { shallow = false } = options;
+          var { shallow = false } = options; // we need to resolve the as value using rewrites for dynamic SSG
+          // pages to allow building the data URL correctly
+
+          var resolvedAs = as;
+
+          if (false) {
+          }
+
+          resolvedAs = delBasePath(resolvedAs);
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(resolvedAs);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1233,6 +1267,31 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         urlIsNew(asPath) {
           return this.asPath !== asPath;
         }
+
+        _resolveHref(parsedHref, pages) {
+          var { pathname } = parsedHref;
+          var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+            delBasePath(pathname)
+          );
+
+          if (cleanPathname === "/404" || cleanPathname === "/_error") {
+            return parsedHref;
+          } // handle resolving href for dynamic routes
+
+          if (!pages.includes(cleanPathname)) {
+            for (var page of pages) {
+              if (
+                (0, _isDynamic.isDynamicRoute)(page) &&
+                (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+              ) {
+                parsedHref.pathname = addBasePath(page);
+                break;
+              }
+            }
+          }
+
+          return parsedHref;
+        }
         /**
          * Prefetch page code, you may wait for the data during page rendering.
          * This feature only works in production!
@@ -1251,7 +1310,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
           var parsed = tryParseRelativeUrl(url);
           if (!parsed) return;
-          var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+          var { pathname } = parsed;
+          var pages = await this.pageLoader.getPageList();
+          parsed = this._resolveHref(parsed, pages);
+
+          if (parsed.pathname !== pathname) {
+            pathname = parsed.pathname;
+            url = (0, _utils.formatWithValidation)(parsed);
+          } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
           if (false) {
           }
@@ -1792,6 +1858,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       if (false) {
       }
 
+      /***/
+    },
+
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
       /***/
     }
   }
Diff for 677f882d2ed8..88fc3a7a7.js
@@ -363,6 +363,13 @@
       /***/
     },
 
+    /***/ S3md: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      /***/
+
+    },
+
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -671,6 +678,80 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
+      function _createForOfIteratorHelper(o, allowArrayLike) {
+        var it;
+        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
+          if (
+            Array.isArray(o) ||
+            (it = _unsupportedIterableToArray(o)) ||
+            (allowArrayLike && o && typeof o.length === "number")
+          ) {
+            if (it) o = it;
+            var i = 0;
+            var F = function F() {};
+            return {
+              s: F,
+              n: function n() {
+                if (i >= o.length) return { done: true };
+                return { done: false, value: o[i++] };
+              },
+              e: function e(_e) {
+                throw _e;
+              },
+              f: F
+            };
+          }
+          throw new TypeError(
+            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+          );
+        }
+        var normalCompletion = true,
+          didErr = false,
+          err;
+        return {
+          s: function s() {
+            it = o[Symbol.iterator]();
+          },
+          n: function n() {
+            var step = it.next();
+            normalCompletion = step.done;
+            return step;
+          },
+          e: function e(_e2) {
+            didErr = true;
+            err = _e2;
+          },
+          f: function f() {
+            try {
+              if (!normalCompletion && it["return"] != null) it["return"]();
+            } finally {
+              if (didErr) throw err;
+            }
+          }
+        };
+      }
+
+      function _unsupportedIterableToArray(o, minLen) {
+        if (!o) return;
+        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
+        var n = Object.prototype.toString.call(o).slice(8, -1);
+        if (n === "Object" && o.constructor) n = o.constructor.name;
+        if (n === "Map" || n === "Set") return Array.from(o);
+        if (
+          n === "Arguments" ||
+          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
+        )
+          return _arrayLikeToArray(o, minLen);
+      }
+
+      function _arrayLikeToArray(arr, len) {
+        if (len == null || len > arr.length) len = arr.length;
+        for (var i = 0, arr2 = new Array(len); i < len; i++) {
+          arr2[i] = arr[i];
+        }
+        return arr2;
+      }
+
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -696,6 +777,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _denormalizePagePath = __webpack_require__("wkBG");
+
+      var _resolveRewrites = _interopRequireDefault(
+        __webpack_require__("S3md")
+      );
+
       function _interopRequireDefault(obj) {
         return obj && obj.__esModule
           ? obj
@@ -1081,13 +1168,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   options
                 ) {
                   var cleanedAs,
+                    pages,
+                    _yield$this$pageLoade,
+                    rewrites,
                     parsed,
+                    _parsed,
                     pathname,
                     searchParams,
                     query,
                     route,
                     _options$shallow,
                     shallow,
+                    resolvedAs,
                     _ref3,
                     asPathname,
                     routeRegex,
@@ -1138,7 +1230,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             }
 
                             this.asPath = cleanedAs;
-                            Router.events.emit("hashChangeStart", as);
+                            Router.events.emit("hashChangeStart", as); // TODO: do we need the resolved href when only a hash change?
+
                             this.changeState(method, url, as, options);
                             this.scrollToHash(cleanedAs);
                             this.notify(this.components[this.route]);
@@ -1146,18 +1239,37 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context.abrupt("return", true);
 
                           case 16:
+                            _context.next = 18;
+                            return this.pageLoader.getPageList();
+
+                          case 18:
+                            pages = _context.sent;
+                            _context.next = 21;
+                            return this.pageLoader.promisedBuildManifest;
+
+                          case 21:
+                            _yield$this$pageLoade = _context.sent;
+                            rewrites = _yield$this$pageLoade.__rewrites;
                             parsed = tryParseRelativeUrl(url);
 
                             if (parsed) {
-                              _context.next = 19;
+                              _context.next = 26;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 19:
-                            (pathname = parsed.pathname),
-                              (searchParams = parsed.searchParams);
+                          case 26:
+                            (_parsed = parsed),
+                              (pathname = _parsed.pathname),
+                              (searchParams = _parsed.searchParams);
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            }
+
                             query = (0, _querystring.searchParamsToUrlQuery)(
                               searchParams
                             ); // url and as should always be prefixed with basePath by this
@@ -1187,15 +1299,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               (shallow =
                                 _options$shallow === void 0
                                   ? false
-                                  : _options$shallow);
+                                  : _options$shallow); // we need to resolve the as value using rewrites for dynamic SSG
+                            // pages to allow building the data URL correctly
+
+                            resolvedAs = as;
+
+                            if (false) {
+                            }
+
+                            resolvedAs = delBasePath(resolvedAs);
 
                             if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                              _context.next = 37;
+                              _context.next = 49;
                               break;
                             }
 
                             (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                              cleanedAs
+                              resolvedAs
                             )),
                               (asPathname = _ref3.pathname);
                             routeRegex = (0, _routeRegex.getRouteRegex)(route);
@@ -1204,7 +1324,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             )(asPathname);
 
                             if (routeMatch) {
-                              _context.next = 36;
+                              _context.next = 48;
                               break;
                             }
 
@@ -1215,7 +1335,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             });
 
                             if (!(missingParams.length > 0)) {
-                              _context.next = 34;
+                              _context.next = 46;
                               break;
                             }
 
@@ -1232,18 +1352,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                             );
 
-                          case 34:
-                            _context.next = 37;
+                          case 46:
+                            _context.next = 49;
                             break;
 
-                          case 36:
+                          case 48:
                             // Merge params into `query`, overwriting any specified in search
                             Object.assign(query, routeMatch);
 
-                          case 37:
+                          case 49:
                             Router.events.emit("routeChangeStart", as);
-                            _context.prev = 38;
-                            _context.next = 41;
+                            _context.prev = 50;
+                            _context.next = 53;
                             return this.getRouteInfo(
                               route,
                               pathname,
@@ -1252,7 +1372,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               shallow
                             );
 
-                          case 41:
+                          case 53:
                             routeInfo = _context.sent;
                             error = routeInfo.error;
                             Router.events.emit("beforeHistoryChange", as);
@@ -1261,7 +1381,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             if (false) {
                             }
 
-                            _context.next = 48;
+                            _context.next = 60;
                             return this.set(
                               route,
                               pathname,
@@ -1270,9 +1390,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               routeInfo
                             );
 
-                          case 48:
+                          case 60:
                             if (!error) {
-                              _context.next = 51;
+                              _context.next = 63;
                               break;
                             }
 
@@ -1283,28 +1403,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             );
                             throw error;
 
-                          case 51:
+                          case 63:
                             if (false) {
                             }
 
                             Router.events.emit("routeChangeComplete", as);
                             return _context.abrupt("return", true);
 
-                          case 56:
-                            _context.prev = 56;
-                            _context.t0 = _context["catch"](38);
+                          case 68:
+                            _context.prev = 68;
+                            _context.t0 = _context["catch"](50);
 
                             if (!_context.t0.cancelled) {
-                              _context.next = 60;
+                              _context.next = 72;
                               break;
                             }
 
                             return _context.abrupt("return", false);
 
-                          case 60:
+                          case 72:
                             throw _context.t0;
 
-                          case 61:
+                          case 73:
                           case "end":
                             return _context.stop();
                         }
@@ -1312,7 +1432,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     },
                     _callee,
                     this,
-                    [[38, 56]]
+                    [[50, 68]]
                   );
                 })
               );
@@ -1730,6 +1850,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             value: function urlIsNew(asPath) {
               return this.asPath !== asPath;
             }
+          },
+          {
+            key: "_resolveHref",
+            value: function _resolveHref(parsedHref, pages) {
+              var pathname = parsedHref.pathname;
+              var cleanPathname = (0, _denormalizePagePath.denormalizePagePath)(
+                delBasePath(pathname)
+              );
+
+              if (cleanPathname === "/404" || cleanPathname === "/_error") {
+                return parsedHref;
+              } // handle resolving href for dynamic routes
+
+              if (!pages.includes(cleanPathname)) {
+                var _iterator = _createForOfIteratorHelper(pages),
+                  _step;
+
+                try {
+                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
+                    var page = _step.value;
+
+                    if (
+                      (0, _isDynamic.isDynamicRoute)(page) &&
+                      (0, _routeRegex.getRouteRegex)(page).re.test(
+                        cleanPathname
+                      )
+                    ) {
+                      parsedHref.pathname = addBasePath(page);
+                      break;
+                    }
+                  }
+                } catch (err) {
+                  _iterator.e(err);
+                } finally {
+                  _iterator.f();
+                }
+              }
+
+              return parsedHref;
+            }
             /**
              * Prefetch page code, you may wait for the data during page rendering.
              * This feature only works in production!
@@ -1745,9 +1905,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var asPath,
                     options,
                     parsed,
+                    _parsed2,
                     pathname,
+                    pages,
                     route,
                     _args4 = arguments;
+
                   return _regeneratorRuntime.wrap(
                     function _callee4$(_context4) {
                       while (1) {
@@ -1771,21 +1934,32 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                             return _context4.abrupt("return");
 
                           case 5:
-                            pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                            (_parsed2 = parsed), (pathname = _parsed2.pathname);
+                            _context4.next = 8;
+                            return this.pageLoader.getPageList();
+
+                          case 8:
+                            pages = _context4.sent;
+                            parsed = this._resolveHref(parsed, pages);
+
+                            if (parsed.pathname !== pathname) {
+                              pathname = parsed.pathname;
+                              url = (0, _utils.formatWithValidation)(parsed);
+                            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                             if (true) {
-                              _context4.next = 8;
+                              _context4.next = 13;
                               break;
                             }
 
                             return _context4.abrupt("return");
 
-                          case 8:
+                          case 13:
                             route = (0,
                             _normalizeTrailingSlash.removePathTrailingSlash)(
                               pathname
                             );
-                            _context4.next = 11;
+                            _context4.next = 16;
                             return Promise.all([
                               this.pageLoader.prefetchData(url, asPath),
                               this.pageLoader[
@@ -1793,7 +1967,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               ](route)
                             ]);
 
-                          case 11:
+                          case 16:
                           case "end":
                             return _context4.stop();
                         }
@@ -1895,9 +2069,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var err = new Error("Loading initial props cancelled");
-                  err.cancelled = true;
-                  throw err;
+                  var _err = new Error("Loading initial props cancelled");
+
+                  _err.cancelled = true;
+                  throw _err;
                 }
 
                 return data;
@@ -3433,6 +3608,28 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ wkBG: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      exports.__esModule = true;
+      exports.normalizePathSep = normalizePathSep;
+      exports.denormalizePagePath = denormalizePagePath;
+      function normalizePathSep(path) {
+        return path.replace(/\\/g, "/");
+      }
+      function denormalizePagePath(page) {
+        page = normalizePathSep(page);
+        if (page.startsWith("/index/")) {
+          page = page.slice(6);
+        } else if (page === "/index") {
+          page = "/";
+        }
+        return page;
+      }
+      //# sourceMappingURL=denormalize-page-path.js.map
+
+      /***/
+    },
+
     /***/ wkBT: /***/ function(module, exports) {
       function _nonIterableRest() {
         throw new TypeError(
Diff for main-2d9e6d6..4da851faa.js
@@ -1559,6 +1559,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           this.loadingRoutes = void 0;
           this.promisedBuildManifest = void 0;
           this.promisedSsgManifest = void 0;
+          this.promisedDevPagesManifest = void 0;
           this.buildId = buildId;
           this.assetPrefix = assetPrefix;
           this.pageCache = {};
@@ -1572,17 +1573,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(function(resolve) {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(function(resolve) {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = function() {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = function() {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(function(resolve) {
@@ -1594,9 +1593,20 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
               };
             }
           });
-        } // Returns a promise for the dependencies for a particular route
+        }
 
         _createClass(PageLoader, [
+          {
+            key: "getPageList",
+            value: function getPageList() {
+              if (true) {
+                return this.promisedBuildManifest.then(function(buildManifest) {
+                  return buildManifest.sortedPages;
+                });
+              } else {
+              }
+            } // Returns a promise for the dependencies for a particular route
+          },
           {
             key: "getDependencies",
             value: function getDependencies(route) {
Diff for main-53fefb2..d8.module.js
@@ -1196,6 +1196,7 @@
           this.loadingRoutes = void 0;
           this.promisedBuildManifest = void 0;
           this.promisedSsgManifest = void 0;
+          this.promisedDevPagesManifest = void 0;
           this.buildId = buildId;
           this.assetPrefix = assetPrefix;
           this.pageCache = {};
@@ -1209,17 +1210,15 @@
             this.loadingRoutes[initialPage] = true;
           }
 
-          if (true) {
-            this.promisedBuildManifest = new Promise(resolve => {
-              if (window.__BUILD_MANIFEST) {
+          this.promisedBuildManifest = new Promise(resolve => {
+            if (window.__BUILD_MANIFEST) {
+              resolve(window.__BUILD_MANIFEST);
+            } else {
+              window.__BUILD_MANIFEST_CB = () => {
                 resolve(window.__BUILD_MANIFEST);
-              } else {
-                window.__BUILD_MANIFEST_CB = () => {
-                  resolve(window.__BUILD_MANIFEST);
-                };
-              }
-            });
-          }
+              };
+            }
+          });
           /** @type {Promise<Set<string>>} */
 
           this.promisedSsgManifest = new Promise(resolve => {
@@ -1231,6 +1230,15 @@
               };
             }
           });
+        }
+
+        getPageList() {
+          if (true) {
+            return this.promisedBuildManifest.then(
+              buildManifest => buildManifest.sortedPages
+            );
+          } else {
+          }
         } // Returns a promise for the dependencies for a particular route
 
         getDependencies(route) {
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-53fefb275ec20b5daed8.module.js"
+      href="/_next/static/chunks/main-5d0fc2e4721200b02098.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7432ef7012751c677416.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55dcddc4eb72216b9437.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-2d9e6d675a94da851faa.js"
+      src="/_next/static/chunks/main-130001635491b9e9cf25.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-53fefb275ec20b5daed8.module.js"
+      src="/_next/static/chunks/main-5d0fc2e4721200b02098.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.8387d6359c388fc3a7a7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0a2278c1e6a0f17105c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7432ef7012751c677416.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55dcddc4eb72216b9437.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-53fefb275ec20b5daed8.module.js"
+      href="/_next/static/chunks/main-5d0fc2e4721200b02098.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7432ef7012751c677416.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55dcddc4eb72216b9437.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-2d9e6d675a94da851faa.js"
+      src="/_next/static/chunks/main-130001635491b9e9cf25.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-53fefb275ec20b5daed8.module.js"
+      src="/_next/static/chunks/main-5d0fc2e4721200b02098.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.8387d6359c388fc3a7a7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0a2278c1e6a0f17105c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7432ef7012751c677416.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55dcddc4eb72216b9437.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-53fefb275ec20b5daed8.module.js"
+      href="/_next/static/chunks/main-5d0fc2e4721200b02098.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7432ef7012751c677416.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55dcddc4eb72216b9437.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-f73ba3fc145972ef83e9.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-2d9e6d675a94da851faa.js"
+      src="/_next/static/chunks/main-130001635491b9e9cf25.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-53fefb275ec20b5daed8.module.js"
+      src="/_next/static/chunks/main-5d0fc2e4721200b02098.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.8387d6359c388fc3a7a7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0a2278c1e6a0f17105c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7432ef7012751c677416.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55dcddc4eb72216b9437.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
buildDuration 15.7s 16s ⚠️ +332ms
nodeModulesSize 57.3 MB 57.3 MB ⚠️ +25.6 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..9460.js gzip 9.93 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-5c21840..49c9.js gzip 6.69 kB N/A N/A
webpack-ccf5..276a.js gzip 751 B 751 B
677f882d2ed8..a830.js gzip N/A 10.3 kB N/A
main-661becd..3755.js gzip N/A 6.72 kB N/A
Overall change 56.5 kB 56.9 kB ⚠️ +402 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
677f882d2ed8..dule.js gzip 5.84 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-c0c009b..dule.js gzip 5.78 kB N/A N/A
webpack-10c7..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.13 kB N/A
main-1667be8..dule.js gzip N/A 5.81 kB N/A
Overall change 51.5 kB 51.8 kB ⚠️ +312 B
Legacy Client Bundles (polyfills)
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
polyfills-75..1629.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-874bd8a..0103.js gzip 1.28 kB 1.28 kB
_error-fa39c..ec40.js gzip 3.45 kB 3.45 kB
hooks-585f07..95a3.js gzip 887 B 887 B
index-c7b63f..fc02.js gzip 227 B 227 B
link-4c2bd9b..eadd.js gzip 1.29 kB 1.29 kB
routerDirect..ebc7.js gzip 284 B 284 B
withRouter-2..db68.js gzip 284 B 284 B
Overall change 7.71 kB 7.71 kB
Client Pages Modern
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_app-97e743e..dule.js gzip 626 B 626 B
_error-b4004..dule.js gzip 2.3 kB 2.3 kB
hooks-696209..dule.js gzip 387 B 387 B
index-a4dd74..dule.js gzip 226 B 226 B
link-236a801..dule.js gzip 1.26 kB 1.26 kB
routerDirect..dule.js gzip 284 B 284 B
withRouter-1..dule.js gzip 282 B 282 B
Overall change 5.37 kB 5.37 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_buildManifest.js gzip 273 B 321 B ⚠️ +48 B
_buildManife..dule.js gzip 279 B 329 B ⚠️ +50 B
Overall change 552 B 650 B ⚠️ +98 B
Serverless bundles Overall decrease ✓
vercel/next.js canary ijjk/next.js add/client-rewrite-handling Change
_error.js 1.03 MB 1.03 MB -765 B
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.03 MB 1.03 MB -765 B
link.js 1.07 MB 1.07 MB ⚠️ +52 B
routerDirect.js 1.06 MB 1.06 MB ⚠️ +52 B
withRouter.js 1.06 MB 1.06 MB ⚠️ +52 B
Overall change 5.26 MB 5.26 MB -1.37 kB
Commit: c63f6b9

@timneutkens timneutkens merged commit 8a489e2 into vercel:canary Aug 13, 2020
@timneutkens timneutkens deleted the add/client-rewrite-handling branch August 13, 2020 12:39
@Timer Timer mentioned this pull request Aug 13, 2020
kodiakhq bot pushed a commit that referenced this pull request Aug 13, 2020
This reduces the code as suggested: #15231 (comment).

Removes these bloated Babel helpers:

```diff
@@ -678,80 +678,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
-      function _createForOfIteratorHelper(o, allowArrayLike) {
-        var it;
-        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
-          if (
-            Array.isArray(o) ||
-            (it = _unsupportedIterableToArray(o)) ||
-            (allowArrayLike && o && typeof o.length === "number")
-          ) {
-            if (it) o = it;
-            var i = 0;
-            var F = function F() {};
-            return {
-              s: F,
-              n: function n() {
-                if (i >= o.length) return { done: true };
-                return { done: false, value: o[i++] };
-              },
-              e: function e(_e) {
-                throw _e;
-              },
-              f: F
-            };
-          }
-          throw new TypeError(
-            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
-          );
-        }
-        var normalCompletion = true,
-          didErr = false,
-          err;
-        return {
-          s: function s() {
-            it = o[Symbol.iterator]();
-          },
-          n: function n() {
-            var step = it.next();
-            normalCompletion = step.done;
-            return step;
-          },
-          e: function e(_e2) {
-            didErr = true;
-            err = _e2;
-          },
-          f: function f() {
-            try {
-              if (!normalCompletion && it["return"] != null) it["return"]();
-            } finally {
-              if (didErr) throw err;
-            }
-          }
-        };
-      }
-
-      function _unsupportedIterableToArray(o, minLen) {
-        if (!o) return;
-        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
-        var n = Object.prototype.toString.call(o).slice(8, -1);
-        if (n === "Object" && o.constructor) n = o.constructor.name;
-        if (n === "Map" || n === "Set") return Array.from(o);
-        if (
-          n === "Arguments" ||
-          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
-        )
-          return _arrayLikeToArray(o, minLen);
-      }
-
-      function _arrayLikeToArray(arr, len) {
-        if (len == null || len > arr.length) len = arr.length;
-        for (var i = 0, arr2 = new Array(len); i < len; i++) {
-          arr2[i] = arr[i];
-        }
-        return arr2;
-      }
-
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -1864,28 +1790,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               } // handle resolving href for dynamic routes
 
               if (!pages.includes(cleanPathname)) {
-                var _iterator = _createForOfIteratorHelper(pages),
-                  _step;
-
-                try {
-                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
-                    var page = _step.value;
-
-                    if (
-                      (0, _isDynamic.isDynamicRoute)(page) &&
-                      (0, _routeRegex.getRouteRegex)(page).re.test(
-                        cleanPathname
-                      )
-                    ) {
-                      parsedHref.pathname = addBasePath(page);
-                      break;
-                    }
+                // eslint-disable-next-line array-callback-return
+                pages.some(function(page) {
+                  if (
+                    (0, _isDynamic.isDynamicRoute)(page) &&
+                    (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+                  ) {
+                    parsedHref.pathname = addBasePath(page);
+                    return true;
                   }
-                } catch (err) {
-                  _iterator.e(err);
-                } finally {
-                  _iterator.f();
-                }
+                });
               }
 
               return parsedHref;
@@ -2069,10 +1983,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var _err = new Error("Loading initial props cancelled");
-
-                  _err.cancelled = true;
-                  throw _err;
+                  var err = new Error("Loading initial props cancelled");
+                  err.cancelled = true;
+                  throw err;
                 }
 
                 return data;
```
m-lautenbach pushed a commit to m-lautenbach/next.js that referenced this pull request Aug 20, 2020
… the client (vercel#15231)

Co-authored-by: Tim Neutkens <timneutkens@me.com>
m-lautenbach pushed a commit to m-lautenbach/next.js that referenced this pull request Aug 20, 2020
This reduces the code as suggested: vercel#15231 (comment).

Removes these bloated Babel helpers:

```diff
@@ -678,80 +678,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _createClass = __webpack_require__("W8MJ");
 
-      function _createForOfIteratorHelper(o, allowArrayLike) {
-        var it;
-        if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
-          if (
-            Array.isArray(o) ||
-            (it = _unsupportedIterableToArray(o)) ||
-            (allowArrayLike && o && typeof o.length === "number")
-          ) {
-            if (it) o = it;
-            var i = 0;
-            var F = function F() {};
-            return {
-              s: F,
-              n: function n() {
-                if (i >= o.length) return { done: true };
-                return { done: false, value: o[i++] };
-              },
-              e: function e(_e) {
-                throw _e;
-              },
-              f: F
-            };
-          }
-          throw new TypeError(
-            "Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
-          );
-        }
-        var normalCompletion = true,
-          didErr = false,
-          err;
-        return {
-          s: function s() {
-            it = o[Symbol.iterator]();
-          },
-          n: function n() {
-            var step = it.next();
-            normalCompletion = step.done;
-            return step;
-          },
-          e: function e(_e2) {
-            didErr = true;
-            err = _e2;
-          },
-          f: function f() {
-            try {
-              if (!normalCompletion && it["return"] != null) it["return"]();
-            } finally {
-              if (didErr) throw err;
-            }
-          }
-        };
-      }
-
-      function _unsupportedIterableToArray(o, minLen) {
-        if (!o) return;
-        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
-        var n = Object.prototype.toString.call(o).slice(8, -1);
-        if (n === "Object" && o.constructor) n = o.constructor.name;
-        if (n === "Map" || n === "Set") return Array.from(o);
-        if (
-          n === "Arguments" ||
-          /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)
-        )
-          return _arrayLikeToArray(o, minLen);
-      }
-
-      function _arrayLikeToArray(arr, len) {
-        if (len == null || len > arr.length) len = arr.length;
-        for (var i = 0, arr2 = new Array(len); i < len; i++) {
-          arr2[i] = arr[i];
-        }
-        return arr2;
-      }
-
       exports.__esModule = true;
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
@@ -1864,28 +1790,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               } // handle resolving href for dynamic routes
 
               if (!pages.includes(cleanPathname)) {
-                var _iterator = _createForOfIteratorHelper(pages),
-                  _step;
-
-                try {
-                  for (_iterator.s(); !(_step = _iterator.n()).done; ) {
-                    var page = _step.value;
-
-                    if (
-                      (0, _isDynamic.isDynamicRoute)(page) &&
-                      (0, _routeRegex.getRouteRegex)(page).re.test(
-                        cleanPathname
-                      )
-                    ) {
-                      parsedHref.pathname = addBasePath(page);
-                      break;
-                    }
+                // eslint-disable-next-line array-callback-return
+                pages.some(function(page) {
+                  if (
+                    (0, _isDynamic.isDynamicRoute)(page) &&
+                    (0, _routeRegex.getRouteRegex)(page).re.test(cleanPathname)
+                  ) {
+                    parsedHref.pathname = addBasePath(page);
+                    return true;
                   }
-                } catch (err) {
-                  _iterator.e(err);
-                } finally {
-                  _iterator.f();
-                }
+                });
               }
 
               return parsedHref;
@@ -2069,10 +1983,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 }
 
                 if (cancelled) {
-                  var _err = new Error("Loading initial props cancelled");
-
-                  _err.cancelled = true;
-                  throw _err;
+                  var err = new Error("Loading initial props cancelled");
+                  err.cancelled = true;
+                  throw err;
                 }
 
                 return data;
```
@madeinspace
Copy link

I think this change is breaking my site, when trying to redirect using
Router.push({
pathname: path,
query,
});

@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.
Labels
create-next-app Related to our CLI tool for quickly starting a new Next.js application. examples Issue/PR related to examples type: next
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants