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

Replace node.js url module with WHATWG URL #14827

Merged
merged 19 commits into from
Jul 13, 2020
Merged

Conversation

Janpot
Copy link
Contributor

@Janpot Janpot commented Jul 3, 2020

Replace url.parse and url.resolve logic with whatwg URL, Bring in a customized format function to handle the node url objects that can be passed to router methods. This eliminates the need for url (and thus native-url) in core. Looks like it shaves off about 2.5Kb, according to the size-limits integration tests.

@ijjk ijjk added the type: next label Jul 3, 2020
@ijjk
Copy link
Member

ijjk commented Jul 3, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 11.9s 11.8s -118ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +4.63 kB
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 1.965 1.91 -0.06
/ avg req/sec 1272.26 1308.89 +36.63
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.198 1.147 -0.05
/error-in-render avg req/sec 2087.05 2179.07 +92.02
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.66 kB ⚠️ +27 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..18e4.js gzip 10.7 kB 10.9 kB ⚠️ +212 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 57.5 kB ⚠️ +239 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.74 kB ⚠️ +22 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.09 kB 7.26 kB ⚠️ +174 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.7 kB 52.9 kB ⚠️ +196 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 954 B 954 B
link.html gzip 959 B 962 B ⚠️ +3 B
withRouter.html gzip 946 B 946 B
Overall change 2.86 kB 2.86 kB ⚠️ +3 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-4ce0c7178d36c3b390c2.js"],
+  "/link": ["static\u002Fpages\u002Flink-2575b1814c71ca69bc5e.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-4c38d18e319a774ec055.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-7ae1b45bce92db689cca.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..13.module.js
@@ -461,20 +461,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -586,6 +600,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.default = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+
+        for (var [key, value] of searchParams.entries()) {
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        }
+
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -644,10 +683,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -658,6 +696,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -685,26 +727,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function parseRelativeUrl(url) {
+        var parsed = new URL(url, "http://n");
+
+        if (parsed.origin !== "http://n") {
+          throw new Error('Absolute URL not allowed: "'.concat(url, '"'));
+        }
+
+        return parsed;
+      }
+
       function fetchNextData(dataHref, isServerRender, cb) {
         var attempts = isServerRender ? 3 : 1;
 
@@ -794,24 +856,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = new URL(url, "http://n"); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -821,8 +885,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -830,7 +892,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = new URL(dataHref, "http://n");
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -966,7 +1029,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -985,7 +1048,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1019,7 +1082,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var pathname;
+            var searchParams;
+
+            try {
+              ({ pathname, searchParams } = parseRelativeUrl(url));
+            } catch (err) {
+              if (false) {
+              }
+
+              return;
+            }
+
+            var query = (0, _searchParamsToUrlQuery.default)(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
 
@@ -1027,14 +1102,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
                   delBasePath(pathname)
                 )
-              : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            } // If asked to change the current URL we should reload the current page
+              : pathname; // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
             // as this should not go into the history (That's how browsers work)
@@ -1051,7 +1119,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var cleanedAs = delBasePath(as);
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = new URL(cleanedAs, "http://n");
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1351,9 +1419,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
+            var pathname;
 
-            if (!pathname || protocol) {
+            try {
+              ({ pathname } = parseRelativeUrl(url));
+            } catch (err) {
               if (false) {
               }
 
@@ -1567,11 +1637,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
Diff for 19b7e98f51cc..079014588.js
@@ -539,20 +539,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -708,6 +722,120 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      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["default"] = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+
+        var _iterator = _createForOfIteratorHelper(searchParams.entries()),
+          _step;
+
+        try {
+          for (_iterator.s(); !(_step = _iterator.n()).done; ) {
+            var _step$value = _slicedToArray(_step.value, 2),
+              key = _step$value[0],
+              value = _step$value[1];
+
+            if (typeof query[key] === "undefined") {
+              query[key] = value;
+            } else if (Array.isArray(query[key])) {
+              query[key].push(value);
+            } else {
+              query[key] = [query[key], value];
+            }
+          }
+        } catch (err) {
+          _iterator.e(err);
+        } finally {
+          _iterator.f();
+        }
+
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -774,10 +902,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -788,6 +915,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -815,26 +946,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function parseRelativeUrl(url) {
+        var parsed = new URL(url, "http://n");
+
+        if (parsed.origin !== "http://n") {
+          throw new Error('Absolute URL not allowed: "'.concat(url, '"'));
+        }
+
+        return parsed;
+      }
+
       function fetchNextData(dataHref, isServerRender, cb) {
         var attempts = isServerRender ? 3 : 1;
 
@@ -927,27 +1078,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _URL = new URL(url, "http://n"),
+              pathname = _URL.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -957,11 +1115,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -969,7 +1122,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _URL2 = new URL(dataHref, "http://n"),
+              pathname = _URL2.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1108,7 +1264,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1132,7 +1288,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1176,10 +1332,24 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var pathname;
+                  var searchParams;
+
+                  try {
+                    var _parseRelativeUrl = parseRelativeUrl(url);
+
+                    pathname = _parseRelativeUrl.pathname;
+                    searchParams = _parseRelativeUrl.searchParams;
+                  } catch (err) {
+                    if (false) {
+                    }
+
+                    return;
+                  }
+
+                  var query = (0, _searchParamsToUrlQuery["default"])(
+                    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
 
@@ -1187,14 +1357,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
                         delBasePath(pathname)
                       )
-                    : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  } // If asked to change the current URL we should reload the current page
+                    : pathname; // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
                   // as this should not go into the history (That's how browsers work)
@@ -1212,8 +1375,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var cleanedAs = delBasePath(as);
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _URL3 = new URL(cleanedAs, "http://n"),
+                      asPathname = _URL3.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1557,11 +1720,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
+                  var pathname;
+
+                  try {
+                    var _parseRelativeUrl2 = parseRelativeUrl(url);
 
-                  if (!pathname || protocol) {
+                    pathname = _parseRelativeUrl2.pathname;
+                  } catch (err) {
                     if (false) {
                     }
 
@@ -1917,11 +2082,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1481,6 +1479,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         __webpack_require__("Lab5")
       );
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       function hasRel(rel, link) {
         try {
           link = document.createElement("link");
@@ -1603,13 +1605,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
-                hrefPathname = _ref.pathname,
-                query = _ref.query,
-                search = _ref.search;
+              var _URL = new URL(href, "http://n"),
+                hrefPathname = _URL.pathname,
+                searchParams = _URL.searchParams,
+                search = _URL.search;
+
+              var query = (0, _searchParamsToUrlQuery["default"])(searchParams);
 
-              var _ref2 = (0, _url.parse)(asPath),
-                asPathname = _ref2.pathname;
+              var _URL2 = new URL(asPath, "http://n"),
+                asPathname = _URL2.pathname;
 
               var route = normalizeRoute(hrefPathname);
 
@@ -1691,8 +1695,8 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
-                hrefPathname = _ref3.pathname;
+              var _URL3 = new URL(href, "http://n"),
+                hrefPathname = _URL3.pathname;
 
               var route = normalizeRoute(hrefPathname);
               return this.promisedSsgManifest.then(function(s, _dataHref) {
@@ -1733,10 +1737,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
                   return;
                 }
 
-                var fire = function fire(_ref4) {
-                  var error = _ref4.error,
-                    page = _ref4.page,
-                    mod = _ref4.mod;
+                var fire = function fire(_ref) {
+                  var error = _ref.error,
+                    page = _ref.page,
+                    mod = _ref.mod;
 
                   _this4.pageRegisterEvents.off(route, fire);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1122,6 +1120,10 @@
         __webpack_require__("Lab5")
       );
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       function hasRel(rel, link) {
         try {
           link = document.createElement("link");
@@ -1228,11 +1230,12 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
+          var { pathname: hrefPathname, searchParams, search } = new URL(
             href,
-            true
+            "http://n"
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var query = (0, _searchParamsToUrlQuery.default)(searchParams);
+          var { pathname: asPathname } = new URL(asPath, "http://n");
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1308,7 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = new URL(href, "http://n");
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.4a3ee1199dbefbe99889.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-e77205bd3f87781c0279.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-0fc7e08a8b2b06dca289.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.58ba8779030a36412357.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.4a3ee1199dbefbe99889.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/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.4a3ee1199dbefbe99889.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-4c38d18e319a774ec055.module.js"
+      href="/_next/static/pages/link-7ae1b45bce92db689cca.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-e77205bd3f87781c0279.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-0fc7e08a8b2b06dca289.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.58ba8779030a36412357.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.4a3ee1199dbefbe99889.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-4ce0c7178d36c3b390c2.js"
+      src="/_next/static/pages/link-2575b1814c71ca69bc5e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-4c38d18e319a774ec055.module.js"
+      src="/_next/static/pages/link-7ae1b45bce92db689cca.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/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.4a3ee1199dbefbe99889.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-e77205bd3f87781c0279.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-0fc7e08a8b2b06dca289.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.58ba8779030a36412357.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.4a3ee1199dbefbe99889.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13s 12.7s -289ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +4.63 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.66 kB ⚠️ +27 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..18e4.js gzip 10.7 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..373c.js gzip N/A 10.9 kB N/A
Overall change 57.2 kB 57.5 kB ⚠️ +239 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.74 kB ⚠️ +22 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.26 kB N/A
Overall change 52.7 kB 52.9 kB ⚠️ +196 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_error.js 876 kB 876 kB -18 B
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 876 kB 876 kB -18 B
link.js 915 kB 916 kB ⚠️ +1.27 kB
routerDirect.js 908 kB 910 kB ⚠️ +1.82 kB
withRouter.js 908 kB 910 kB ⚠️ +1.82 kB
Overall change 4.49 MB 4.5 MB ⚠️ +4.88 kB
Commit: 4c24825

@ijjk
Copy link
Member

ijjk commented Jul 3, 2020

Failing test suites

Commit: 4c24825

test/integration/size-limit/test/index.test.js

  • Production response size > should not increase the overall response size of default build
Expand output

● Production response size › should not increase the overall response size of default build

expect(received).toBeLessThanOrEqual(expected)

Expected: <= 1024
Received:    1353

  82 |     // These numbers are without gzip compression!
  83 |     const delta = responseSizesBytes - 264 * 1024
> 84 |     expect(delta).toBeLessThanOrEqual(1024) // don't increase size more than 1kb
     |                   ^
  85 |     expect(delta).toBeGreaterThanOrEqual(-1024) // don't decrease size more than 1kb without updating target
  86 |   })
  87 | 

  at Object.<anonymous> (integration/size-limit/test/index.test.js:84:19)

@ijjk
Copy link
Member

ijjk commented Jul 3, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 12.3s 12.5s ⚠️ +211ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +4.7 kB
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 1.954 2.004 ⚠️ +0.05
/ avg req/sec 1279.7 1247.43 ⚠️ -32.27
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.265 1.15 -0.11
/error-in-render avg req/sec 1975.61 2174.49 +198.88
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.66 kB ⚠️ +27 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..18e4.js gzip 10.7 kB 10.9 kB ⚠️ +170 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 57.4 kB ⚠️ +197 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.74 kB ⚠️ +22 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.09 kB 7.28 kB ⚠️ +184 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.7 kB 52.9 kB ⚠️ +206 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 954 B 955 B ⚠️ +1 B
link.html gzip 959 B 962 B ⚠️ +3 B
withRouter.html gzip 946 B 946 B
Overall change 2.86 kB 2.86 kB ⚠️ +4 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-4ce0c7178d36c3b390c2.js"],
+  "/link": ["static\u002Fpages\u002Flink-2575b1814c71ca69bc5e.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-4c38d18e319a774ec055.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-7ae1b45bce92db689cca.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..13.module.js
@@ -461,20 +461,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -586,6 +600,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.default = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -644,10 +683,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -658,6 +696,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -685,26 +727,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function parseRelativeUrl(url) {
+        var parsed = new URL(url, "http://n");
+
+        if (parsed.origin !== "http://n") {
+          throw new Error('Absolute URL not allowed: "'.concat(url, '"'));
+        }
+
+        return parsed;
+      }
+
       function fetchNextData(dataHref, isServerRender, cb) {
         var attempts = isServerRender ? 3 : 1;
 
@@ -794,24 +856,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = new URL(url, "http://n"); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -821,8 +885,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -830,7 +892,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = new URL(dataHref, "http://n");
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -966,7 +1029,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -985,7 +1048,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1019,7 +1082,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var pathname;
+            var searchParams;
+
+            try {
+              ({ pathname, searchParams } = parseRelativeUrl(url));
+            } catch (err) {
+              if (false) {
+              }
+
+              return;
+            }
+
+            var query = (0, _searchParamsToUrlQuery.default)(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
 
@@ -1027,14 +1102,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
                   delBasePath(pathname)
                 )
-              : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            } // If asked to change the current URL we should reload the current page
+              : pathname; // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
             // as this should not go into the history (That's how browsers work)
@@ -1051,7 +1119,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var cleanedAs = delBasePath(as);
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = new URL(cleanedAs, "http://n");
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1351,9 +1419,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
+            var pathname;
 
-            if (!pathname || protocol) {
+            try {
+              ({ pathname } = parseRelativeUrl(url));
+            } catch (err) {
               if (false) {
               }
 
@@ -1567,11 +1637,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
Diff for 19b7e98f51cc..079014588.js
@@ -539,20 +539,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -708,6 +722,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports["default"] = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -774,10 +817,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -788,6 +830,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -815,26 +861,46 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function parseRelativeUrl(url) {
+        var parsed = new URL(url, "http://n");
+
+        if (parsed.origin !== "http://n") {
+          throw new Error('Absolute URL not allowed: "'.concat(url, '"'));
+        }
+
+        return parsed;
+      }
+
       function fetchNextData(dataHref, isServerRender, cb) {
         var attempts = isServerRender ? 3 : 1;
 
@@ -927,27 +993,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _URL = new URL(url, "http://n"),
+              pathname = _URL.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -957,11 +1030,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -969,7 +1037,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _URL2 = new URL(dataHref, "http://n"),
+              pathname = _URL2.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1108,7 +1179,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1132,7 +1203,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1176,10 +1247,24 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var pathname;
+                  var searchParams;
+
+                  try {
+                    var _parseRelativeUrl = parseRelativeUrl(url);
+
+                    pathname = _parseRelativeUrl.pathname;
+                    searchParams = _parseRelativeUrl.searchParams;
+                  } catch (err) {
+                    if (false) {
+                    }
+
+                    return;
+                  }
+
+                  var query = (0, _searchParamsToUrlQuery["default"])(
+                    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
 
@@ -1187,14 +1272,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
                         delBasePath(pathname)
                       )
-                    : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  } // If asked to change the current URL we should reload the current page
+                    : pathname; // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
                   // as this should not go into the history (That's how browsers work)
@@ -1212,8 +1290,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var cleanedAs = delBasePath(as);
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _URL3 = new URL(cleanedAs, "http://n"),
+                      asPathname = _URL3.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1557,11 +1635,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
+                  var pathname;
+
+                  try {
+                    var _parseRelativeUrl2 = parseRelativeUrl(url);
 
-                  if (!pathname || protocol) {
+                    pathname = _parseRelativeUrl2.pathname;
+                  } catch (err) {
                     if (false) {
                     }
 
@@ -1917,11 +1997,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1481,6 +1479,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
         __webpack_require__("Lab5")
       );
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       function hasRel(rel, link) {
         try {
           link = document.createElement("link");
@@ -1603,13 +1605,15 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
-                hrefPathname = _ref.pathname,
-                query = _ref.query,
-                search = _ref.search;
+              var _URL = new URL(href, "http://n"),
+                hrefPathname = _URL.pathname,
+                searchParams = _URL.searchParams,
+                search = _URL.search;
+
+              var query = (0, _searchParamsToUrlQuery["default"])(searchParams);
 
-              var _ref2 = (0, _url.parse)(asPath),
-                asPathname = _ref2.pathname;
+              var _URL2 = new URL(asPath, "http://n"),
+                asPathname = _URL2.pathname;
 
               var route = normalizeRoute(hrefPathname);
 
@@ -1691,8 +1695,8 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
-                hrefPathname = _ref3.pathname;
+              var _URL3 = new URL(href, "http://n"),
+                hrefPathname = _URL3.pathname;
 
               var route = normalizeRoute(hrefPathname);
               return this.promisedSsgManifest.then(function(s, _dataHref) {
@@ -1733,10 +1737,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
                   return;
                 }
 
-                var fire = function fire(_ref4) {
-                  var error = _ref4.error,
-                    page = _ref4.page,
-                    mod = _ref4.mod;
+                var fire = function fire(_ref) {
+                  var error = _ref.error,
+                    page = _ref.page,
+                    mod = _ref.mod;
 
                   _this4.pageRegisterEvents.off(route, fire);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1122,6 +1120,10 @@
         __webpack_require__("Lab5")
       );
 
+      var _searchParamsToUrlQuery = _interopRequireDefault(
+        __webpack_require__("cE6r")
+      );
+
       function hasRel(rel, link) {
         try {
           link = document.createElement("link");
@@ -1228,11 +1230,12 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
+          var { pathname: hrefPathname, searchParams, search } = new URL(
             href,
-            true
+            "http://n"
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var query = (0, _searchParamsToUrlQuery.default)(searchParams);
+          var { pathname: asPathname } = new URL(asPath, "http://n");
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1308,7 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = new URL(href, "http://n");
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e95146ad2b4129e53453.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-e77205bd3f87781c0279.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-0fc7e08a8b2b06dca289.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.982b286a07ceb2dfef44.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e95146ad2b4129e53453.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/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e95146ad2b4129e53453.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-4c38d18e319a774ec055.module.js"
+      href="/_next/static/pages/link-7ae1b45bce92db689cca.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-e77205bd3f87781c0279.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-0fc7e08a8b2b06dca289.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.982b286a07ceb2dfef44.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e95146ad2b4129e53453.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-4ce0c7178d36c3b390c2.js"
+      src="/_next/static/pages/link-2575b1814c71ca69bc5e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-4c38d18e319a774ec055.module.js"
+      src="/_next/static/pages/link-7ae1b45bce92db689cca.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/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e95146ad2b4129e53453.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-e77205bd3f87781c0279.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-0fc7e08a8b2b06dca289.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-528e1d347f371631b854.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.982b286a07ceb2dfef44.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e95146ad2b4129e53453.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13.6s 13.8s ⚠️ +167ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +4.7 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.66 kB ⚠️ +27 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..18e4.js gzip 10.7 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..93f5.js gzip N/A 10.9 kB N/A
Overall change 57.2 kB 57.4 kB ⚠️ +197 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.74 kB ⚠️ +22 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.28 kB N/A
Overall change 52.7 kB 52.9 kB ⚠️ +206 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.3 kB 26.3 kB
Overall change 26.3 kB 26.3 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_error.js 876 kB 876 kB -18 B
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 876 kB 876 kB -18 B
link.js 915 kB 916 kB ⚠️ +1.28 kB
routerDirect.js 908 kB 910 kB ⚠️ +1.83 kB
withRouter.js 908 kB 910 kB ⚠️ +1.83 kB
Overall change 4.49 MB 4.5 MB ⚠️ +4.91 kB
Commit: 2e9cdc8

@ijjk
Copy link
Member

ijjk commented Jul 4, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 12.9s 12.7s -203ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +6.69 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 2.273 2.192 -0.08
/ avg req/sec 1099.81 1140.69 +40.88
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.389 1.437 ⚠️ +0.05
/error-in-render avg req/sec 1800.02 1739.53 ⚠️ -60.49
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +45 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..18e4.js gzip 10.7 kB 11 kB ⚠️ +268 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 57.5 kB ⚠️ +313 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.75 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.09 kB 7.35 kB ⚠️ +263 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.7 kB 53 kB ⚠️ +303 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 954 B 954 B
link.html gzip 958 B 962 B ⚠️ +4 B
withRouter.html gzip 945 B 946 B ⚠️ +1 B
Overall change 2.86 kB 2.86 kB ⚠️ +5 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-4ce0c7178d36c3b390c2.js"],
+  "/link": ["static\u002Fpages\u002Flink-2575b1814c71ca69bc5e.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-4c38d18e319a774ec055.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-7ae1b45bce92db689cca.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..13.module.js
@@ -461,20 +461,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -586,6 +600,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -644,10 +683,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -658,6 +696,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -685,26 +727,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       function fetchNextData(dataHref, isServerRender, cb) {
         var attempts = isServerRender ? 3 : 1;
 
@@ -794,24 +857,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -821,8 +886,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -830,7 +893,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -966,7 +1032,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -985,7 +1051,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1019,7 +1085,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1027,14 +1098,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
                   delBasePath(pathname)
                 )
-              : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            } // If asked to change the current URL we should reload the current page
+              : pathname; // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
             // as this should not go into the history (That's how browsers work)
@@ -1051,7 +1115,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var cleanedAs = delBasePath(as);
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1351,14 +1416,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1567,11 +1627,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1630,6 +1690,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..079014588.js
@@ -539,20 +539,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -708,6 +722,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -774,10 +817,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -788,6 +830,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -815,26 +861,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       function fetchNextData(dataHref, isServerRender, cb) {
         var attempts = isServerRender ? 3 : 1;
 
@@ -927,27 +994,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -957,11 +1031,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -969,7 +1038,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1108,7 +1180,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1132,7 +1204,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1176,10 +1248,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1187,14 +1261,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
                         delBasePath(pathname)
                       )
-                    : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  } // If asked to change the current URL we should reload the current page
+                    : pathname; // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
                   // as this should not go into the history (That's how browsers work)
@@ -1212,8 +1279,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   var cleanedAs = delBasePath(as);
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1557,16 +1626,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1917,11 +1979,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1983,6 +2045,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1477,6 +1475,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1603,12 +1605,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1691,7 +1697,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1118,6 +1116,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1228,11 +1230,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1309,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-0455152c81f8102736be.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.904faf499160df6b048a.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-ce281d5a1f8fd13d9bfd.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-0455152c81f8102736be.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.8c4a64c970d3eacf308f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.904faf499160df6b048a.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/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-0455152c81f8102736be.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.904faf499160df6b048a.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-4c38d18e319a774ec055.module.js"
+      href="/_next/static/pages/link-7ae1b45bce92db689cca.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-ce281d5a1f8fd13d9bfd.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-0455152c81f8102736be.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.8c4a64c970d3eacf308f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.904faf499160df6b048a.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-4ce0c7178d36c3b390c2.js"
+      src="/_next/static/pages/link-2575b1814c71ca69bc5e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-4c38d18e319a774ec055.module.js"
+      src="/_next/static/pages/link-7ae1b45bce92db689cca.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/runtime/main-452e034f836fd2253b3a.module.js"
+      href="/_next/static/runtime/main-0455152c81f8102736be.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.904faf499160df6b048a.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-a402689d595ce1baa2c7.js"
+      src="/_next/static/runtime/main-ce281d5a1f8fd13d9bfd.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-452e034f836fd2253b3a.module.js"
+      src="/_next/static/runtime/main-0455152c81f8102736be.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.15dc873ded6079014588.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.8c4a64c970d3eacf308f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.12a66c28dfec2bca8613.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.904faf499160df6b048a.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13.8s 14.1s ⚠️ +314ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +6.69 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +45 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..18e4.js gzip 10.7 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..01f2.js gzip N/A 11 kB N/A
Overall change 57.2 kB 57.5 kB ⚠️ +313 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.75 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.35 kB N/A
Overall change 52.7 kB 53 kB ⚠️ +303 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_error.js 876 kB 876 kB -18 B
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 876 kB 876 kB -18 B
link.js 915 kB 917 kB ⚠️ +2.04 kB
routerDirect.js 908 kB 911 kB ⚠️ +2.59 kB
withRouter.js 908 kB 911 kB ⚠️ +2.59 kB
Overall change 4.49 MB 4.5 MB ⚠️ +7.19 kB
Commit: 8cf6b12

@ijjk
Copy link
Member

ijjk commented Jul 7, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 9.9s 10.4s ⚠️ +546ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +7.64 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 1.796 1.726 -0.07
/ avg req/sec 1392.16 1448.62 +56.46
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.038 1.076 ⚠️ +0.04
/error-in-render avg req/sec 2408.25 2322.91 ⚠️ -85.34
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +45 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..c646.js gzip 10.7 kB 11 kB ⚠️ +267 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 57.5 kB ⚠️ +312 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.75 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB 7.36 kB ⚠️ +261 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
Overall change 52.7 kB 53 kB ⚠️ +301 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 954 B 952 B -2 B
link.html gzip 960 B 960 B
withRouter.html gzip 946 B 944 B -2 B
Overall change 2.86 kB 2.86 kB -4 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-d0cd3d2b80934d6c003a.js"],
+  "/link": ["static\u002Fpages\u002Flink-2575b1814c71ca69bc5e.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-5a10d6c964f4c88363cd.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-7ae1b45bce92db689cca.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..73.module.js
@@ -461,20 +461,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -586,6 +600,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -644,10 +683,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -658,6 +696,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -685,26 +727,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -796,24 +859,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -823,8 +888,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -832,7 +895,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -973,7 +1039,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -992,7 +1058,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1026,7 +1092,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1035,14 +1106,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1059,7 +1122,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1362,14 +1426,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1578,11 +1637,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1641,6 +1700,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..d0645a966.js
@@ -539,20 +539,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -708,6 +722,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -774,10 +817,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -788,6 +830,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -815,26 +861,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -929,27 +996,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -959,11 +1033,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -971,7 +1040,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1115,7 +1187,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1139,7 +1211,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1183,10 +1255,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1195,14 +1269,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1220,8 +1286,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1568,16 +1636,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1928,11 +1989,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _url.format)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1994,6 +2055,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1477,6 +1475,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1603,12 +1605,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1691,7 +1697,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1118,6 +1116,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1228,11 +1230,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1309,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.0b1f3f6ef86f42218329.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.558f442c347e847e9138.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.0b1f3f6ef86f42218329.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.0b1f3f6ef86f42218329.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      href="/_next/static/pages/link-7ae1b45bce92db689cca.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.558f442c347e847e9138.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.0b1f3f6ef86f42218329.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-d0cd3d2b80934d6c003a.js"
+      src="/_next/static/pages/link-2575b1814c71ca69bc5e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      src="/_next/static/pages/link-7ae1b45bce92db689cca.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.0b1f3f6ef86f42218329.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.558f442c347e847e9138.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.0b1f3f6ef86f42218329.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 10.8s 11.2s ⚠️ +396ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +7.64 kB
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +45 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..c646.js gzip 10.7 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..cd82.js gzip N/A 11 kB N/A
Overall change 57.2 kB 57.5 kB ⚠️ +312 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.75 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 7.36 kB N/A
Overall change 52.7 kB 53 kB ⚠️ +301 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_error.js 876 kB 876 kB -18 B
404.html 4.17 kB 4.17 kB
hooks.html 3.79 kB 3.79 kB
index.js 877 kB 877 kB -18 B
link.js 915 kB 917 kB ⚠️ +2.4 kB
routerDirect.js 909 kB 911 kB ⚠️ +2.59 kB
withRouter.js 909 kB 911 kB ⚠️ +2.59 kB
Overall change 4.49 MB 4.5 MB ⚠️ +7.54 kB
Commit: 5391c7b

@ijjk
Copy link
Member

ijjk commented Jul 7, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 11s 11.8s ⚠️ +771ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +15.1 kB
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 1.916 1.914 0
/ avg req/sec 1305.02 1306.4 +1.38
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.159 1.112 -0.05
/error-in-render avg req/sec 2156.62 2248.46 +91.84
Client Bundles (main, webpack, commons) Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +45 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..c646.js gzip 10.7 kB 9.76 kB -932 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 56.3 kB -887 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.75 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 6.16 kB N/A
Overall change 52.7 kB 51.8 kB -901 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 954 B 955 B ⚠️ +1 B
link.html gzip 960 B 962 B ⚠️ +2 B
withRouter.html gzip 946 B 945 B -1 B
Overall change 2.86 kB 2.86 kB ⚠️ +2 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-d0cd3d2b80934d6c003a.js"],
+  "/link": ["static\u002Fpages\u002Flink-2575b1814c71ca69bc5e.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-5a10d6c964f4c88363cd.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-7ae1b45bce92db689cca.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..73.module.js
@@ -216,227 +216,96 @@
       /***/
     },
 
-    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var assign = Object.assign.bind(Object);
-      module.exports = assign;
-      module.exports.default = module.exports;
-      //# sourceMappingURL=object-assign.js.map
 
-      /***/
-    },
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var { auth, hostname } = urlObj;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
           }
         }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
       }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
+
+      /***/
+    },
+
+    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      var assign = Object.assign.bind(Object);
+      module.exports = assign;
+      module.exports.default = module.exports;
+      //# sourceMappingURL=object-assign.js.map
 
       /***/
     },
@@ -461,20 +330,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -586,6 +469,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -644,10 +552,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -658,6 +565,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -685,26 +596,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -796,24 +728,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -823,8 +757,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -832,7 +764,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -973,7 +908,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -992,7 +927,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1026,7 +961,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1035,14 +975,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1059,7 +991,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1362,14 +1295,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1479,7 +1407,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1578,11 +1506,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1641,6 +1569,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..d0645a966.js
@@ -216,6 +216,91 @@
       /***/
     },
 
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
+
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var auth = urlObj.auth,
+          hostname = urlObj.hostname;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
+          }
+        }
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
+      }
+
+      /***/
+    },
+
     /***/ J4zp: /***/ function(module, exports, __webpack_require__) {
       var arrayWithHoles = __webpack_require__("wTVA");
 
@@ -249,221 +334,6 @@
       /***/
     },
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
-          }
-        }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
-      }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
-
-      /***/
-    },
-
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -539,20 +409,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -708,6 +592,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -774,10 +687,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -788,6 +700,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -815,26 +731,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -929,27 +866,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -959,11 +903,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -971,7 +910,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1115,7 +1057,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1139,7 +1081,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1183,10 +1125,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1195,14 +1139,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1220,8 +1156,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1568,16 +1506,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1762,7 +1693,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1928,11 +1859,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1994,6 +1925,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1477,6 +1475,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1603,12 +1605,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1691,7 +1697,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1118,6 +1116,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1228,11 +1230,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1309,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.5af7a607daa3649f7d9a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      href="/_next/static/pages/link-7ae1b45bce92db689cca.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.5af7a607daa3649f7d9a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-d0cd3d2b80934d6c003a.js"
+      src="/_next/static/pages/link-2575b1814c71ca69bc5e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      src="/_next/static/pages/link-7ae1b45bce92db689cca.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.5af7a607daa3649f7d9a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 12.6s 12s -570ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +15.1 kB
Client Bundles (main, webpack, commons) Overall decrease ✓

@ijjk
Copy link
Member

ijjk commented Jul 7, 2020

Failing test suites

Commit: 4a269c9

test/integration/size-limit/test/index.test.js

  • Production response size > should not increase the overall response size of default build
  • Production response size > should not increase the overall response size of modern build
Expand output

● Production response size › should not increase the overall response size of default build

expect(received).toBeGreaterThanOrEqual(expected)

Expected: >= -1024
Received:    -2299

  83 |     const delta = responseSizesBytes - 264 * 1024
  84 |     expect(delta).toBeLessThanOrEqual(1024) // don't increase size more than 1kb
> 85 |     expect(delta).toBeGreaterThanOrEqual(-1024) // don't decrease size more than 1kb without updating target
     |                   ^
  86 |   })
  87 | 
  88 |   it('should not increase the overall response size of modern build', async () => {

  at Object.<anonymous> (integration/size-limit/test/index.test.js:85:19)
      at runMicrotasks (<anonymous>)

● Production response size › should not increase the overall response size of modern build

expect(received).toBeGreaterThanOrEqual(expected)

Expected: >= -1024
Received:    -2517

  103 |     const delta = responseSizesBytes - 169 * 1024
  104 |     expect(delta).toBeLessThanOrEqual(1024) // don't increase size more than 1kb
> 105 |     expect(delta).toBeGreaterThanOrEqual(-1024) // don't decrease size more than 1kb without updating target
      |                   ^
  106 |   })
  107 | })
  108 | 

  at Object.<anonymous> (integration/size-limit/test/index.test.js:105:19)
      at runMicrotasks (<anonymous>)

@Janpot Janpot changed the title Remove url.parse and url.resolve from client Replace node.js url module with WHATWG URL Jul 7, 2020
@ijjk
Copy link
Member

ijjk commented Jul 7, 2020

Stats from current PR

Default Server Mode (Decrease detected ✓)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13s 13.3s ⚠️ +273ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +15.1 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 2.298 2.286 -0.01
/ avg req/sec 1087.92 1093.42 +5.5
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.512 1.54 ⚠️ +0.03
/error-in-render avg req/sec 1652.99 1623.53 ⚠️ -29.46
Client Bundles (main, webpack, commons) Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +45 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..c646.js gzip 10.7 kB 9.76 kB -932 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 56.3 kB -887 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.75 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 6.16 kB N/A
Overall change 52.7 kB 51.8 kB -901 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 268 B
_buildManife..dule.js gzip 272 B 272 B
Overall change 540 B 540 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 954 B 955 B ⚠️ +1 B
link.html gzip 960 B 962 B ⚠️ +2 B
withRouter.html gzip 946 B 945 B -1 B
Overall change 2.86 kB 2.86 kB ⚠️ +2 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-d0cd3d2b80934d6c003a.js"],
+  "/link": ["static\u002Fpages\u002Flink-2575b1814c71ca69bc5e.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-5a10d6c964f4c88363cd.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-7ae1b45bce92db689cca.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..73.module.js
@@ -216,227 +216,96 @@
       /***/
     },
 
-    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var assign = Object.assign.bind(Object);
-      module.exports = assign;
-      module.exports.default = module.exports;
-      //# sourceMappingURL=object-assign.js.map
 
-      /***/
-    },
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var { auth, hostname } = urlObj;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
           }
         }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
       }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
+
+      /***/
+    },
+
+    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      var assign = Object.assign.bind(Object);
+      module.exports = assign;
+      module.exports.default = module.exports;
+      //# sourceMappingURL=object-assign.js.map
 
       /***/
     },
@@ -461,20 +330,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -586,6 +469,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -644,10 +552,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -658,6 +565,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -685,26 +596,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -796,24 +728,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -823,8 +757,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -832,7 +764,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -973,7 +908,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -992,7 +927,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1026,7 +961,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1035,14 +975,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1059,7 +991,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1362,14 +1295,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1479,7 +1407,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1578,11 +1506,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1641,6 +1569,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..d0645a966.js
@@ -216,6 +216,91 @@
       /***/
     },
 
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
+
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var auth = urlObj.auth,
+          hostname = urlObj.hostname;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
+          }
+        }
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
+      }
+
+      /***/
+    },
+
     /***/ J4zp: /***/ function(module, exports, __webpack_require__) {
       var arrayWithHoles = __webpack_require__("wTVA");
 
@@ -249,221 +334,6 @@
       /***/
     },
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
-          }
-        }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
-      }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
-
-      /***/
-    },
-
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -539,20 +409,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -708,6 +592,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -774,10 +687,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -788,6 +700,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -815,26 +731,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(router, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(router.pathname, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router, url)),
+          as: as ? addBasePath(resolveHref(router, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -929,27 +866,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -959,11 +903,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -971,7 +910,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1115,7 +1057,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1139,7 +1081,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1183,10 +1125,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1195,14 +1139,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1220,8 +1156,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1568,16 +1506,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1762,7 +1693,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1928,11 +1859,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1994,6 +1925,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1477,6 +1475,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1603,12 +1605,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1691,7 +1697,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1118,6 +1116,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1228,11 +1230,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1309,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.5af7a607daa3649f7d9a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      href="/_next/static/pages/link-7ae1b45bce92db689cca.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.5af7a607daa3649f7d9a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-d0cd3d2b80934d6c003a.js"
+      src="/_next/static/pages/link-2575b1814c71ca69bc5e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      src="/_next/static/pages/link-7ae1b45bce92db689cca.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.5af7a607daa3649f7d9a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.003c702daa1bf76c526e.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 14.4s 14.2s -142ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +15.1 kB
Client Bundles (main, webpack, commons) Overall d Post job cleanup. [command]/usr/bin/git version git version 2.27.0 [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand [command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || : [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader http.https://github.com/.extraheader [command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader [command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || : Cleaning up orphan processes Commit: a3bde0c

@ijjk
Copy link
Member

ijjk commented Jul 7, 2020

Stats from current PR

Default Server Mode (Decrease detected ✓)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13.2s 13.2s ⚠️ +16ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +15.1 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 2.136 2.173 ⚠️ +0.04
/ avg req/sec 1170.31 1150.47 ⚠️ -19.84
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.363 1.365 0
/error-in-render avg req/sec 1833.73 1831.47 ⚠️ -2.26
Client Bundles (main, webpack, commons) Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +45 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..c646.js gzip 10.7 kB 9.76 kB -932 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 56.3 kB -887 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.71 kB 5.75 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 6.16 kB N/A
Overall change 52.7 kB 51.8 kB -900 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 268 B 267 B -1 B
_buildManife..dule.js gzip 272 B 274 B ⚠️ +2 B
Overall change 540 B 541 B ⚠️ +1 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 954 B 954 B
link.html gzip 960 B 959 B -1 B
withRouter.html gzip 946 B 946 B
Overall change 2.86 kB 2.86 kB -1 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-d0cd3d2b80934d6c003a.js"],
+  "/link": ["static\u002Fpages\u002Flink-a137a4943ccdc4a32d4e.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-5a10d6c964f4c88363cd.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-94bae7829dba3f86cda2.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..73.module.js
@@ -216,227 +216,96 @@
       /***/
     },
 
-    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var assign = Object.assign.bind(Object);
-      module.exports = assign;
-      module.exports.default = module.exports;
-      //# sourceMappingURL=object-assign.js.map
 
-      /***/
-    },
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var { auth, hostname } = urlObj;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
           }
         }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
       }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
+
+      /***/
+    },
+
+    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      var assign = Object.assign.bind(Object);
+      module.exports = assign;
+      module.exports.default = module.exports;
+      //# sourceMappingURL=object-assign.js.map
 
       /***/
     },
@@ -461,20 +330,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -586,6 +469,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -644,10 +552,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -658,6 +565,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -685,26 +596,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -796,24 +728,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -823,8 +757,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -832,7 +764,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -973,7 +908,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -992,7 +927,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1026,7 +961,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1035,14 +975,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1059,7 +991,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1362,14 +1295,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1479,7 +1407,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1578,11 +1506,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1641,6 +1569,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..d0645a966.js
@@ -216,6 +216,91 @@
       /***/
     },
 
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
+
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var auth = urlObj.auth,
+          hostname = urlObj.hostname;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
+          }
+        }
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
+      }
+
+      /***/
+    },
+
     /***/ J4zp: /***/ function(module, exports, __webpack_require__) {
       var arrayWithHoles = __webpack_require__("wTVA");
 
@@ -249,221 +334,6 @@
       /***/
     },
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
-          }
-        }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
-      }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
-
-      /***/
-    },
-
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -539,20 +409,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -708,6 +592,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -774,10 +687,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -788,6 +700,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -815,26 +731,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -929,27 +866,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -959,11 +903,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -971,7 +910,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1115,7 +1057,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1139,7 +1081,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1183,10 +1125,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1195,14 +1139,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1220,8 +1156,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1568,16 +1506,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1762,7 +1693,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1928,11 +1859,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1994,6 +1925,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("Invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1477,6 +1475,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1603,12 +1605,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1691,7 +1697,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1118,6 +1116,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1228,11 +1230,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1309,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.9586ca9ff0df97a234c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.7b6dde3d281e71e10493.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.9586ca9ff0df97a234c2.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.9586ca9ff0df97a234c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      href="/_next/static/pages/link-94bae7829dba3f86cda2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.7b6dde3d281e71e10493.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.9586ca9ff0df97a234c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-d0cd3d2b80934d6c003a.js"
+      src="/_next/static/pages/link-a137a4943ccdc4a32d4e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-5a10d6c964f4c88363cd.module.js"
+      src="/_next/static/pages/link-94bae7829dba3f86cda2.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/runtime/main-ebe998339a21eae32e6a.module.js"
+      href="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.9586ca9ff0df97a234c2.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-df9bcf41d7b3b9849696.js"
+      src="/_next/static/runtime/main-fc794a38af0026d951ef.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-ebe998339a21eae32e6a.module.js"
+      src="/_next/static/runtime/main-2f125c0a9a68f7fef842.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.ee8f39bc6cdd0645a966.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.7b6dde3d281e71e10493.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.6892bb0ce1e47d97f973.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.9586ca9ff0df97a234c2.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 14.1s 14.4s ⚠️ +235ms
nodeModulesSize 66.1 MB 66.1 MB ⚠️ +15.1 kB
Post job cleanup. [command]/usr/bin/git version git version 2.27.0 [command]/usr/bin/git config --local --name-only --get-regexp core\.sshCommand [command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || : [command]/usr/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader http.https://github.com/.extraheader [command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader [command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || : Cleaning up orphan processes Commit: 3fb78c2

@Janpot Janpot marked this pull request as ready for review July 7, 2020 18:08
@Janpot Janpot requested review from ijjk and lfades as code owners July 7, 2020 18:08
@Janpot Janpot requested review from Timer and timneutkens as code owners July 7, 2020 18:08
Timer
Timer previously approved these changes Jul 13, 2020
Copy link
Member

@Timer Timer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work, thanks!

@ijjk
Copy link
Member

ijjk commented Jul 13, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 12.8s 12.5s -363ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 2.222 2.136 -0.09
/ avg req/sec 1125.2 1170.38 +45.18
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.512 1.46 -0.05
/error-in-render avg req/sec 1653.51 1712.59 +59.08
Client Bundles (main, webpack, commons) Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.63 kB 6.67 kB ⚠️ +44 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..e4a8.js gzip 10.7 kB 9.77 kB -924 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.2 kB 56.3 kB -880 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.72 kB 5.76 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 6.16 kB N/A
Overall change 52.7 kB 51.8 kB -893 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 267 B 267 B
_buildManife..dule.js gzip 272 B 273 B ⚠️ +1 B
Overall change 539 B 540 B ⚠️ +1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 953 B 954 B ⚠️ +1 B
link.html gzip 961 B 962 B ⚠️ +1 B
withRouter.html gzip 945 B 946 B ⚠️ +1 B
Overall change 2.86 kB 2.86 kB ⚠️ +3 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-af971698baef7eb52a5a.js"],
+  "/link": ["static\u002Fpages\u002Flink-384139ace1609fd05ce0.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-7ed56a2be20f20a492a2.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-481c9ef0fea508bf4d17.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..b697ae7df.js
@@ -216,6 +216,91 @@
       /***/
     },
 
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
+
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var auth = urlObj.auth,
+          hostname = urlObj.hostname;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
+          }
+        }
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
+      }
+
+      /***/
+    },
+
     /***/ J4zp: /***/ function(module, exports, __webpack_require__) {
       var arrayWithHoles = __webpack_require__("wTVA");
 
@@ -249,221 +334,6 @@
       /***/
     },
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
-          }
-        }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
-      }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
-
-      /***/
-    },
-
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -539,20 +409,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -712,6 +596,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -778,10 +691,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -792,6 +704,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -819,26 +735,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -933,27 +870,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -963,11 +907,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -975,7 +914,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1119,7 +1061,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1143,7 +1085,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1187,10 +1129,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1199,14 +1143,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1224,8 +1160,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1572,16 +1510,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1766,7 +1697,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1932,11 +1863,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1998,6 +1929,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..de.module.js
@@ -216,227 +216,96 @@
       /***/
     },
 
-    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var assign = Object.assign.bind(Object);
-      module.exports = assign;
-      module.exports.default = module.exports;
-      //# sourceMappingURL=object-assign.js.map
 
-      /***/
-    },
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var { auth, hostname } = urlObj;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
           }
         }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
       }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
+
+      /***/
+    },
+
+    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      var assign = Object.assign.bind(Object);
+      module.exports = assign;
+      module.exports.default = module.exports;
+      //# sourceMappingURL=object-assign.js.map
 
       /***/
     },
@@ -461,20 +330,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -590,6 +473,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -648,10 +556,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -662,6 +569,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -689,26 +600,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -800,24 +732,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -827,8 +761,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -836,7 +768,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -977,7 +912,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -996,7 +931,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1030,7 +965,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1039,14 +979,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1063,7 +995,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1366,14 +1299,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1483,7 +1411,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1582,11 +1510,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1645,6 +1573,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1467,8 +1467,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1477,6 +1475,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1603,12 +1605,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1691,7 +1697,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1108,8 +1108,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1118,6 +1116,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _getAssetPathFromRoute = _interopRequireDefault(
         __webpack_require__("Lab5")
       );
@@ -1228,11 +1230,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1305,7 +1309,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-d9a3ec854854c174b592.module.js"
+      href="/_next/static/runtime/main-7448dc7ef2d140ca3a2f.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-64fd39eecd782af2bcd5.js"
+      src="/_next/static/runtime/main-190247b49d7b44e75ef9.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-d9a3ec854854c174b592.module.js"
+      src="/_next/static/runtime/main-7448dc7ef2d140ca3a2f.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.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/runtime/main-d9a3ec854854c174b592.module.js"
+      href="/_next/static/runtime/main-7448dc7ef2d140ca3a2f.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      href="/_next/static/pages/link-481c9ef0fea508bf4d17.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-64fd39eecd782af2bcd5.js"
+      src="/_next/static/runtime/main-190247b49d7b44e75ef9.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-d9a3ec854854c174b592.module.js"
+      src="/_next/static/runtime/main-7448dc7ef2d140ca3a2f.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-af971698baef7eb52a5a.js"
+      src="/_next/static/pages/link-384139ace1609fd05ce0.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      src="/_next/static/pages/link-481c9ef0fea508bf4d17.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/runtime/main-d9a3ec854854c174b592.module.js"
+      href="/_next/static/runtime/main-7448dc7ef2d140ca3a2f.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-64fd39eecd782af2bcd5.js"
+      src="/_next/static/runtime/main-190247b49d7b44e75ef9.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-d9a3ec854854c174b592.module.js"
+      src="/_next/static/runtime/main-7448dc7ef2d140ca3a2f.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13.6s 13.6s -20ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB

Timer
Timer previously approved these changes Jul 13, 2020
@ijjk
Copy link
Member

ijjk commented Jul 13, 2020

Failing test suites

Commit: 6faf1af

test/integration/build-output/test/index.test.js

  • Build Output > Basic Application Output > should not deviate from snapshot
Expand output

● Build Output › Basic Application Output › should not deviate from snapshot

expect(received).toBeLessThanOrEqual(expected)

Expected: <= 0
Received:    0.02999999999999936

  114 |       expect(webpackSize.endsWith('B')).toBe(true)
  115 | 
> 116 |       expect(parseFloat(mainSize) - 6.4).toBeLessThanOrEqual(0)
      |                                          ^
  117 |       expect(mainSize.endsWith('kB')).toBe(true)
  118 | 
  119 |       expect(parseFloat(frameworkSize) - 41).toBeLessThanOrEqual(0)

  at Object.<anonymous> (integration/build-output/test/index.test.js:116:42)

@ijjk
Copy link
Member

ijjk commented Jul 13, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 12.3s 12.4s ⚠️ +122ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 2.193 2.145 -0.05
/ avg req/sec 1139.95 1165.66 +25.71
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.426 1.421 0
/error-in-render avg req/sec 1752.55 1759.87 +7.32
Client Bundles (main, webpack, commons) Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.67 kB 6.72 kB ⚠️ +42 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..e4a8.js gzip 10.7 kB 9.77 kB -924 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.3 kB 56.4 kB -882 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.75 kB 5.79 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 6.16 kB N/A
Overall change 52.7 kB 51.9 kB -893 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 267 B 267 B
_buildManife..dule.js gzip 272 B 273 B ⚠️ +1 B
Overall change 539 B 540 B ⚠️ +1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 955 B 956 B ⚠️ +1 B
link.html gzip 962 B 962 B
withRouter.html gzip 946 B 947 B ⚠️ +1 B
Overall change 2.86 kB 2.87 kB ⚠️ +2 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-af971698baef7eb52a5a.js"],
+  "/link": ["static\u002Fpages\u002Flink-384139ace1609fd05ce0.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-7ed56a2be20f20a492a2.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-481c9ef0fea508bf4d17.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..b697ae7df.js
@@ -216,6 +216,91 @@
       /***/
     },
 
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
+
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var auth = urlObj.auth,
+          hostname = urlObj.hostname;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
+          }
+        }
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
+      }
+
+      /***/
+    },
+
     /***/ J4zp: /***/ function(module, exports, __webpack_require__) {
       var arrayWithHoles = __webpack_require__("wTVA");
 
@@ -249,221 +334,6 @@
       /***/
     },
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
-          }
-        }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
-      }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
-
-      /***/
-    },
-
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -539,20 +409,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -712,6 +596,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -778,10 +691,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -792,6 +704,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -819,26 +735,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -933,27 +870,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -963,11 +907,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -975,7 +914,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1119,7 +1061,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1143,7 +1085,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1187,10 +1129,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1199,14 +1143,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1224,8 +1160,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1572,16 +1510,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1766,7 +1697,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1932,11 +1863,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1998,6 +1929,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..de.module.js
@@ -216,227 +216,96 @@
       /***/
     },
 
-    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var assign = Object.assign.bind(Object);
-      module.exports = assign;
-      module.exports.default = module.exports;
-      //# sourceMappingURL=object-assign.js.map
 
-      /***/
-    },
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var { auth, hostname } = urlObj;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
           }
         }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
       }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
+
+      /***/
+    },
+
+    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      var assign = Object.assign.bind(Object);
+      module.exports = assign;
+      module.exports.default = module.exports;
+      //# sourceMappingURL=object-assign.js.map
 
       /***/
     },
@@ -461,20 +330,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -590,6 +473,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -648,10 +556,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -662,6 +569,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -689,26 +600,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -800,24 +732,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -827,8 +761,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -836,7 +768,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -977,7 +912,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -996,7 +931,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1030,7 +965,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1039,14 +979,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1063,7 +995,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1366,14 +1299,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1483,7 +1411,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1582,11 +1510,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1645,6 +1573,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1482,8 +1482,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1492,6 +1490,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _escapePathDelimiters = _interopRequireDefault(
         __webpack_require__("fcRV")
       );
@@ -1622,12 +1624,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1712,7 +1718,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1121,8 +1121,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1131,6 +1129,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _escapePathDelimiters = _interopRequireDefault(
         __webpack_require__("fcRV")
       );
@@ -1245,11 +1247,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1322,7 +1326,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.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/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      href="/_next/static/pages/link-481c9ef0fea508bf4d17.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-af971698baef7eb52a5a.js"
+      src="/_next/static/pages/link-384139ace1609fd05ce0.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      src="/_next/static/pages/link-481c9ef0fea508bf4d17.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/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13.4s 13.5s ⚠️ +89ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB

</detail
Post job cleanup.
[command]/usr/bin/git version
git version 2.27.0
[command]/usr/bin/git config --local --name-only --get-regexp core.sshCommand
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core.sshCommand' && git config --local --unset-all 'core.sshCommand' || :
[command]/usr/bin/git config --local --name-only --get-regexp http.https://github.com/.extraheader
http.https://github.com/.extraheader
[command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'http.https://github.com/.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :
Cleaning up orphan processes
Commit: 6faf1af

@ijjk
Copy link
Member

ijjk commented Jul 13, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 10.5s 10.3s -193ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 1.779 1.766 -0.01
/ avg req/sec 1405.51 1415.71 +10.2
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.203 1.199 0
/error-in-render avg req/sec 2078.63 2085.7 +7.07
Client Bundles (main, webpack, commons) Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.67 kB 6.72 kB ⚠️ +42 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..e4a8.js gzip 10.7 kB 9.77 kB -924 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.3 kB 56.4 kB -882 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.75 kB 5.79 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 6.16 kB N/A
Overall change 52.7 kB 51.9 kB -893 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 267 B 267 B
_buildManife..dule.js gzip 272 B 273 B ⚠️ +1 B
Overall change 539 B 540 B ⚠️ +1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 955 B 956 B ⚠️ +1 B
link.html gzip 962 B 962 B
withRouter.html gzip 946 B 947 B ⚠️ +1 B
Overall change 2.86 kB 2.87 kB ⚠️ +2 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-af971698baef7eb52a5a.js"],
+  "/link": ["static\u002Fpages\u002Flink-384139ace1609fd05ce0.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-7ed56a2be20f20a492a2.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-481c9ef0fea508bf4d17.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..b697ae7df.js
@@ -216,6 +216,91 @@
       /***/
     },
 
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
+
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var auth = urlObj.auth,
+          hostname = urlObj.hostname;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
+          }
+        }
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
+      }
+
+      /***/
+    },
+
     /***/ J4zp: /***/ function(module, exports, __webpack_require__) {
       var arrayWithHoles = __webpack_require__("wTVA");
 
@@ -249,221 +334,6 @@
       /***/
     },
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
-          }
-        }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
-      }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
-
-      /***/
-    },
-
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -539,20 +409,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -712,6 +596,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -778,10 +691,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -792,6 +704,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -819,26 +735,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -933,27 +870,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -963,11 +907,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -975,7 +914,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1119,7 +1061,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1143,7 +1085,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1187,10 +1129,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1199,14 +1143,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1224,8 +1160,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1572,16 +1510,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1766,7 +1697,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1932,11 +1863,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1998,6 +1929,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..de.module.js
@@ -216,227 +216,96 @@
       /***/
     },
 
-    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var assign = Object.assign.bind(Object);
-      module.exports = assign;
-      module.exports.default = module.exports;
-      //# sourceMappingURL=object-assign.js.map
 
-      /***/
-    },
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var { auth, hostname } = urlObj;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
           }
         }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
       }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
+
+      /***/
+    },
+
+    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      var assign = Object.assign.bind(Object);
+      module.exports = assign;
+      module.exports.default = module.exports;
+      //# sourceMappingURL=object-assign.js.map
 
       /***/
     },
@@ -461,20 +330,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -590,6 +473,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -648,10 +556,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -662,6 +569,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -689,26 +600,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -800,24 +732,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -827,8 +761,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -836,7 +768,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -977,7 +912,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -996,7 +931,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1030,7 +965,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1039,14 +979,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1063,7 +995,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1366,14 +1299,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1483,7 +1411,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1582,11 +1510,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1645,6 +1573,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1482,8 +1482,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1492,6 +1490,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _escapePathDelimiters = _interopRequireDefault(
         __webpack_require__("fcRV")
       );
@@ -1622,12 +1624,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1712,7 +1718,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1121,8 +1121,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1131,6 +1129,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _escapePathDelimiters = _interopRequireDefault(
         __webpack_require__("fcRV")
       );
@@ -1245,11 +1247,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1322,7 +1326,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.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/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      href="/_next/static/pages/link-481c9ef0fea508bf4d17.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-af971698baef7eb52a5a.js"
+      src="/_next/static/pages/link-384139ace1609fd05ce0.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      src="/_next/static/pages/link-481c9ef0fea508bf4d17.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/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 11.2s 12s ⚠️ +817ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB

<detai
Post job cleanup.
[command]/usr/bin/git version
git version 2.27.0
[command]/usr/bin/git config --local --name-only --get-regexp core.sshCommand
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core.sshCommand' && git config --local --unset-all 'core.sshCommand' || :
[command]/usr/bin/git config --local --name-only --get-regexp http.https://github.com/.extraheader
http.https://github.com/.extraheader
[command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'http.https://github.com/.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :
Cleaning up orphan processes
Commit: a523c06

@ijjk
Copy link
Member

ijjk commented Jul 13, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 12.1s 12s -35ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
/ failed reqs 0 0
/ total time (seconds) 2.126 2.067 -0.06
/ avg req/sec 1175.71 1209.43 +33.72
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.46 1.406 -0.05
/error-in-render avg req/sec 1712.57 1778.02 +65.45
Client Bundles (main, webpack, commons) Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.js gzip 6.67 kB 6.72 kB ⚠️ +42 B
webpack-HASH.js gzip 751 B 751 B
19b7e98f51cc..e4a8.js gzip 10.7 kB 9.77 kB -924 B
framework.HASH.js gzip 39.1 kB 39.1 kB
Overall change 57.3 kB 56.4 kB -882 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js wip-remove-url Change
main-HASH.module.js gzip 5.75 kB 5.79 kB ⚠️ +40 B
webpack-HASH..dule.js gzip 751 B 751 B
19b7e98f51cc..dule.js gzip 7.1 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
19b7e98f51cc..dule.js gzip N/A 6.16 kB N/A
Overall change 52.7 kB 51.9 kB -893 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js wip-remove-url Change
polyfills-HASH.js gzip 26.4 kB 26.4 kB
Overall change 26.4 kB 26.4 kB
Client Build Manifests Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
_buildManifest.js gzip 267 B 267 B
_buildManife..dule.js gzip 272 B 273 B ⚠️ +1 B
Overall change 539 B 540 B ⚠️ +1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
index.html gzip 955 B 956 B ⚠️ +1 B
link.html gzip 962 B 962 B
withRouter.html gzip 946 B 947 B ⚠️ +1 B
Overall change 2.86 kB 2.87 kB ⚠️ +2 B

Diffs

Diff for _buildManifest.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-f35cd1774d910f5523ed.js"],
   "/_error": ["static\u002Fpages\u002F_error-f39e6723c6acde17325a.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-9e216cd51bf04b309e08.js"],
-  "/link": ["static\u002Fpages\u002Flink-af971698baef7eb52a5a.js"],
+  "/link": ["static\u002Fpages\u002Flink-384139ace1609fd05ce0.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-b95d3f54c75949a43da6.js"
   ],
Diff for _buildManifest.module.js
@@ -2,7 +2,7 @@ self.__BUILD_MANIFEST = {
   "/": ["static\u002Fpages\u002Findex-da343bca3b67f1bcf42d.module.js"],
   "/_error": ["static\u002Fpages\u002F_error-b3c4c3f8dbb1417657e6.module.js"],
   "/hooks": ["static\u002Fpages\u002Fhooks-dc8f274035a2839a1e61.module.js"],
-  "/link": ["static\u002Fpages\u002Flink-7ed56a2be20f20a492a2.module.js"],
+  "/link": ["static\u002Fpages\u002Flink-481c9ef0fea508bf4d17.module.js"],
   "/routerDirect": [
     "static\u002Fpages\u002FrouterDirect-c62f258dff7fece0a732.module.js"
   ],
Diff for 19b7e98f51cc..b697ae7df.js
@@ -216,6 +216,91 @@
       /***/
     },
 
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
+
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var auth = urlObj.auth,
+          hostname = urlObj.hostname;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
+          }
+        }
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
+      }
+
+      /***/
+    },
+
     /***/ J4zp: /***/ function(module, exports, __webpack_require__) {
       var arrayWithHoles = __webpack_require__("wTVA");
 
@@ -249,221 +334,6 @@
       /***/
     },
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
-          }
-        }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
-      }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
-
-      /***/
-    },
-
     /***/ SksO: /***/ function(module, exports) {
       function _setPrototypeOf(o, p) {
         module.exports = _setPrototypeOf =
@@ -539,20 +409,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -712,6 +596,35 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      var _slicedToArray = __webpack_require__("J4zp");
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(function(_ref) {
+          var _ref2 = _slicedToArray(_ref, 2),
+            key = _ref2[0],
+            value = _ref2[1];
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -778,10 +691,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -792,6 +704,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -819,26 +735,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -933,27 +870,34 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var pathname = _this.pathname,
+              var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query: query
                 }),
                 (0, _utils.getURL)()
               );
 
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var _e$state = e.state,
+              url = _e$state.url,
+              as = _e$state.as,
+              options = _e$state.options;
+
+            var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(url),
+              pathname = _ref2.pathname; // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               _this.isSsr &&
-              e.state.as === _this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === _this.pathname
+              as === _this.asPath &&
+              pathname === _this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -963,11 +907,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var _e$state = e.state,
-              url = _e$state.url,
-              as = _e$state.as,
-              options = _e$state.options;
-
             if (false) {
             }
 
@@ -975,7 +914,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = function(dataHref) {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(dataHref),
+              pathname = _ref3.pathname;
+
+            pathname = prepareRoute(pathname);
             return true && _this.sdc[pathname]
               ? Promise.resolve(_this.sdc[dataHref])
               : fetchNextData(dataHref, _this.isSsr, function(data) {
@@ -1119,7 +1061,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs = prepareUrlAs(url, as);
+                var _prepareUrlAs = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs.url;
                 as = _prepareUrlAs.as;
@@ -1143,7 +1085,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   arguments.length > 2 && arguments[2] !== undefined
                     ? arguments[2]
                     : {};
-                var _prepareUrlAs2 = prepareUrlAs(url, as);
+                var _prepareUrlAs2 = prepareUrlAs(this, url, as);
 
                 url = _prepareUrlAs2.url;
                 as = _prepareUrlAs2.as;
@@ -1187,10 +1129,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     return resolve(true);
                   }
 
-                  var _ref2 = (0, _url.parse)(url, true),
-                    pathname = _ref2.pathname,
-                    query = _ref2.query,
-                    protocol = _ref2.protocol; // url and as should always be prefixed with basePath by this
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname,
+                    searchParams = parsed.searchParams;
+                  var query = (0,
+                  _searchParamsToUrlQuery.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
 
@@ -1199,14 +1143,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         delBasePath(pathname)
                       )
                     : pathname;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return resolve(false);
-                  }
-
                   var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
                   // (not location.reload() but reload getInitialProps and other Next.js stuffs)
                   // We also need to set the method = replaceState always
@@ -1224,8 +1160,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       _options$shallow === void 0 ? false : _options$shallow;
 
                   if ((0, _isDynamic.isDynamicRoute)(route)) {
-                    var _ref3 = (0, _url.parse)(cleanedAs),
-                      asPathname = _ref3.pathname;
+                    var _ref4 = (0, _parseRelativeUrl.parseRelativeUrl)(
+                        cleanedAs
+                      ),
+                      asPathname = _ref4.pathname;
 
                     var routeRegex = (0, _routeRegex.getRouteRegex)(route);
                     var routeMatch = (0, _routeMatcher.getRouteMatcher)(
@@ -1572,16 +1510,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     ? arguments[2]
                     : {};
                 return new Promise(function(resolve, reject) {
-                  var _ref4 = (0, _url.parse)(url),
-                    pathname = _ref4.pathname,
-                    protocol = _ref4.protocol;
-
-                  if (!pathname || protocol) {
-                    if (false) {
-                    }
-
-                    return;
-                  } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+                  var parsed = tryParseRelativeUrl(url);
+                  if (!parsed) return;
+                  var pathname = parsed.pathname; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
                   if (false) {
                   }
@@ -1766,7 +1697,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1932,11 +1863,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1998,6 +1929,45 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+
+        var _URL = new URL(url, resolvedBase),
+          pathname = _URL.pathname,
+          searchParams = _URL.searchParams,
+          search = _URL.search,
+          hash = _URL.hash,
+          href = _URL.href,
+          origin = _URL.origin;
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname: pathname,
+          searchParams: searchParams,
+          search: search,
+          hash: hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for 19b7e98f51cc..de.module.js
@@ -216,227 +216,96 @@
       /***/
     },
 
-    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+    /***/ "6D7l": /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var assign = Object.assign.bind(Object);
-      module.exports = assign;
-      module.exports.default = module.exports;
-      //# sourceMappingURL=object-assign.js.map
 
-      /***/
-    },
+      exports.__esModule = true;
+      exports.formatUrl = formatUrl;
 
-    /***/ QmWs: /***/ function(module, exports, __webpack_require__) {
-      var t,
-        e =
-          (t = __webpack_require__("s4NR")) &&
-          "object" == typeof t &&
-          "default" in t
-            ? t.default
-            : t,
-        o = /https?|ftp|gopher|file/;
-      function r(t) {
-        "string" == typeof t && (t = d(t));
-        var r = (function(t, e, o) {
-          var r = t.auth,
-            a = t.hostname,
-            s = t.protocol || "",
-            p = t.pathname || "",
-            n = t.hash || "",
-            c = t.query || "",
-            h = !1;
-          (r = r ? encodeURIComponent(r).replace(/%3A/i, ":") + "@" : ""),
-            t.host
-              ? (h = r + t.host)
-              : a &&
-                ((h = r + (~a.indexOf(":") ? "[" + a + "]" : a)),
-                t.port && (h += ":" + t.port)),
-            c && "object" == typeof c && (c = e.encode(c));
-          var l = t.search || (c && "?" + c) || "";
-          return (
-            s && ":" !== s.substr(-1) && (s += ":"),
-            t.slashes || ((!s || o.test(s)) && !1 !== h)
-              ? ((h = "//" + (h || "")), p && "/" !== p[0] && (p = "/" + p))
-              : h || (h = ""),
-            n && "#" !== n[0] && (n = "#" + n),
-            l && "?" !== l[0] && (l = "?" + l),
-            {
-              protocol: s,
-              host: h,
-              pathname: (p = p.replace(/[?#]/g, encodeURIComponent)),
-              search: (l = l.replace("#", "%23")),
-              hash: n
-            }
-          );
-        })(t, e, o);
-        return "" + r.protocol + r.host + r.pathname + r.search + r.hash;
-      }
-      var a = "http://",
-        s = "w.w",
-        p = a + s,
-        n = /^([a-z0-9.+-]*:\/\/\/)([a-z0-9.+-]:\/*)?/i,
-        c = /https?|ftp|gopher|file/;
-      function h(t, e) {
-        var o = "string" == typeof t ? d(t) : t;
-        t = "object" == typeof t ? r(t) : t;
-        var s = d(e),
-          h = "";
-        o.protocol &&
-          !o.slashes &&
-          ((h = o.protocol),
-          (t = t.replace(o.protocol, "")),
-          (h += "/" === e[0] || "/" === t[0] ? "/" : "")),
-          h &&
-            s.protocol &&
-            ((h = ""),
-            s.slashes || ((h = s.protocol), (e = e.replace(s.protocol, ""))));
-        var l = t.match(n);
-        l &&
-          !s.protocol &&
-          ((t = t.substr((h = l[1] + (l[2] || "")).length)),
-          /^\/\/[^/]/.test(e) && (h = h.slice(0, -1)));
-        var i = new URL(t, p + "/"),
-          u = new URL(e, i).toString().replace(p, ""),
-          f = s.protocol || o.protocol;
-        return (
-          (f += o.slashes || s.slashes ? "//" : ""),
-          !h && f ? (u = u.replace(a, f)) : h && (u = u.replace(a, "")),
-          c.test(u) ||
-            ~e.indexOf(".") ||
-            "/" === t.slice(-1) ||
-            "/" === e.slice(-1) ||
-            "/" !== u.slice(-1) ||
-            (u = u.slice(0, -1)),
-          h && (u = h + ("/" === u[0] ? u.substr(1) : u)),
-          u
-        );
-      }
-      function l() {}
-      (l.prototype.parse = d),
-        (l.prototype.format = r),
-        (l.prototype.resolve = h),
-        (l.prototype.resolveObject = h);
-      var i = /^https?|ftp|gopher|file/,
-        u = /^(.*?)([#?].*)/,
-        f = /^([a-z0-9.+-]*:)(\/{0,3})(.*)/i,
-        m = /^([a-z0-9.+-]*:)?\/\/\/*/i,
-        v = /^([a-z0-9.+-]*:)(\/{0,2})\[(.*)\]$/i;
-      function d(t, o, a) {
-        if (
-          (void 0 === o && (o = !1),
-          void 0 === a && (a = !1),
-          t && "object" == typeof t && t instanceof l)
-        )
-          return t;
-        var n = (t = t.trim()).match(u);
-        (t = n ? n[1].replace(/\\/g, "/") + n[2] : t.replace(/\\/g, "/")),
-          v.test(t) && "/" !== t.slice(-1) && (t += "/");
-        var c = !/(^javascript)/.test(t) && t.match(f),
-          h = m.test(t),
-          d = "";
-        c &&
-          (i.test(c[1]) || ((d = c[1].toLowerCase()), (t = "" + c[2] + c[3])),
-          c[2] ||
-            ((h = !1),
-            i.test(c[1]) ? ((d = c[1]), (t = "" + c[3])) : (t = "//" + c[3])),
-          (3 !== c[2].length && 1 !== c[2].length) ||
-            ((d = c[1]), (t = "/" + c[3])));
-        var g,
-          y = (n ? n[1] : t).match(/^https?:\/\/[^/]+(:[0-9]+)(?=\/|$)/),
-          b = y && y[1],
-          C = new l(),
-          U = "",
-          j = "";
-        try {
-          g = new URL(t);
-        } catch (e) {
-          (U = e),
-            d ||
-              a ||
-              !/^\/\//.test(t) ||
-              /^\/\/.+[@.]/.test(t) ||
-              ((j = "/"), (t = t.substr(1)));
-          try {
-            g = new URL(t, p);
-          } catch (t) {
-            return (C.protocol = d), (C.href = d), C;
+      var _querystring = __webpack_require__("s4NR"); // Format function modified from nodejs
+      // Copyright Joyent, Inc. and other Node contributors.
+      //
+      // Permission is hereby granted, free of charge, to any person obtaining a
+      // copy of this software and associated documentation files (the
+      // "Software"), to deal in the Software without restriction, including
+      // without limitation the rights to use, copy, modify, merge, publish,
+      // distribute, sublicense, and/or sell copies of the Software, and to permit
+      // persons to whom the Software is furnished to do so, subject to the
+      // following conditions:
+      //
+      // The above copyright notice and this permission notice shall be included
+      // in all copies or substantial portions of the Software.
+      //
+      // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+      // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+      // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+      // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+      // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+      // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+      // USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+      var slashedProtocols = /https?|ftp|gopher|file/;
+
+      function formatUrl(urlObj) {
+        var { auth, hostname } = urlObj;
+        var protocol = urlObj.protocol || "";
+        var pathname = urlObj.pathname || "";
+        var hash = urlObj.hash || "";
+        var query = urlObj.query || "";
+        var host = false;
+        auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
+
+        if (urlObj.host) {
+          host = auth + urlObj.host;
+        } else if (hostname) {
+          host =
+            auth +
+            (~hostname.indexOf(":") ? "[".concat(hostname, "]") : hostname);
+
+          if (urlObj.port) {
+            host += ":" + urlObj.port;
           }
         }
-        (C.slashes = h && !j),
-          (C.host = g.host === s ? "" : g.host),
-          (C.hostname =
-            g.hostname === s ? "" : g.hostname.replace(/(\[|\])/g, "")),
-          (C.protocol = U ? d || null : g.protocol),
-          (C.search = g.search.replace(/\\/g, "%5C")),
-          (C.hash = g.hash.replace(/\\/g, "%5C"));
-        var w = t.split("#");
-        !C.search && ~w[0].indexOf("?") && (C.search = "?"),
-          C.hash || "" !== w[1] || (C.hash = "#"),
-          (C.query = o ? e.decode(g.search.substr(1)) : C.search.substr(1)),
-          (C.pathname =
-            j +
-            (c
-              ? (function(t) {
-                  return t
-                    .replace(/['^|`]/g, function(t) {
-                      return (
-                        "%" +
-                        t
-                          .charCodeAt()
-                          .toString(16)
-                          .toUpperCase()
-                      );
-                    })
-                    .replace(/((?:%[0-9A-F]{2})+)/g, function(t, e) {
-                      try {
-                        return decodeURIComponent(e)
-                          .split("")
-                          .map(function(t) {
-                            var e = t.charCodeAt();
-                            return e > 256 || /^[a-z0-9]$/i.test(t)
-                              ? t
-                              : "%" + e.toString(16).toUpperCase();
-                          })
-                          .join("");
-                      } catch (t) {
-                        return e;
-                      }
-                    });
-                })(g.pathname)
-              : g.pathname)),
-          "about:" === C.protocol &&
-            "blank" === C.pathname &&
-            ((C.protocol = ""), (C.pathname = "")),
-          U && "/" !== t[0] && (C.pathname = C.pathname.substr(1)),
-          d &&
-            !i.test(d) &&
-            "/" !== t.slice(-1) &&
-            "/" === C.pathname &&
-            (C.pathname = ""),
-          (C.path = C.pathname + C.search),
-          (C.auth = [g.username, g.password]
-            .map(decodeURIComponent)
-            .filter(Boolean)
-            .join(":")),
-          (C.port = g.port),
-          b && !C.host.endsWith(b) && ((C.host += b), (C.port = b.slice(1))),
-          (C.href = j ? "" + C.pathname + C.search + C.hash : r(C));
-        var x = /^(file)/.test(C.href) ? ["host", "hostname"] : [];
-        return (
-          Object.keys(C).forEach(function(t) {
-            ~x.indexOf(t) || (C[t] = C[t] || null);
-          }),
-          C
-        );
+
+        if (query && typeof query === "object") {
+          // query = '' + new URLSearchParams(query);
+          query = (0, _querystring.encode)(query);
+        }
+
+        var search = urlObj.search || (query && "?".concat(query)) || "";
+        if (protocol && protocol.substr(-1) !== ":") protocol += ":";
+
+        if (
+          urlObj.slashes ||
+          ((!protocol || slashedProtocols.test(protocol)) && host !== false)
+        ) {
+          host = "//" + (host || "");
+          if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
+        } else if (!host) {
+          host = "";
+        }
+
+        if (hash && hash[0] !== "#") hash = "#" + hash;
+        if (search && search[0] !== "?") search = "?" + search;
+        pathname = pathname.replace(/[?#]/g, encodeURIComponent);
+        search = search.replace("#", "%23");
+        return ""
+          .concat(protocol)
+          .concat(host)
+          .concat(pathname)
+          .concat(search)
+          .concat(hash);
       }
-      (exports.parse = d),
-        (exports.format = r),
-        (exports.resolve = h),
-        (exports.resolveObject = function(t, e) {
-          return d(h(t, e));
-        }),
-        (exports.Url = l);
-      //# sourceMappingURL=index.js.map
+
+      /***/
+    },
+
+    /***/ Qetd: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+      var assign = Object.assign.bind(Object);
+      module.exports = assign;
+      module.exports.default = module.exports;
+      //# sourceMappingURL=object-assign.js.map
 
       /***/
     },
@@ -461,20 +330,34 @@
       exports.__esModule = true;
       exports.removePathTrailingSlash = removePathTrailingSlash;
       exports.normalizeTrailingSlash = normalizeTrailingSlash;
+      /**
+       * Removes the trailing slash of a path if there is one. Preserves the root path `/`.
+       */
 
       function removePathTrailingSlash(path) {
         return path.endsWith("/") && path !== "/" ? path.slice(0, -1) : path;
       }
+      /**
+       * Normalizes the trailing slash of a path according to the `trailingSlash` option
+       * in `next.config.js`.
+       */
 
       var normalizePathTrailingSlash = false
         ? undefined
         : removePathTrailingSlash;
+      /**
+       * Normalizes the trailing slash of the path of a parsed url. Non-destructive.
+       */
 
       function normalizeTrailingSlash(url) {
         var normalizedPath =
           url.pathname && normalizePathTrailingSlash(url.pathname);
         return url.pathname === normalizedPath
           ? url
+          : url instanceof URL
+          ? Object.assign(new URL(url.href), {
+              pathname: normalizedPath
+            })
           : Object.assign({}, url, {
               pathname: normalizedPath
             });
@@ -590,6 +473,31 @@
       /***/
     },
 
+    /***/ cE6r: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.searchParamsToUrlQuery = searchParamsToUrlQuery;
+
+      function searchParamsToUrlQuery(searchParams) {
+        var query = {};
+        Array.from(searchParams.entries()).forEach(_ref => {
+          var [key, value] = _ref;
+
+          if (typeof query[key] === "undefined") {
+            query[key] = value;
+          } else if (Array.isArray(query[key])) {
+            query[key].push(value);
+          } else {
+            query[key] = [query[key], value];
+          }
+        });
+        return query;
+      }
+
+      /***/
+    },
+
     /***/ dZ6Y: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
@@ -648,10 +556,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.__esModule = true;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
+      exports.resolveHref = resolveHref;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _utils = __webpack_require__("g/15");
@@ -662,6 +569,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _normalizeTrailingSlash = __webpack_require__("X24+");
 
       function _interopRequireDefault(obj) {
@@ -689,26 +600,47 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           delBasePath(path || "/")
         );
       }
+      /**
+       * Resolves a given hyperlink with a certain router state (basePath not included).
+       * Preserves absolute urls.
+       */
 
-      function formatUrl(url) {
-        return url
-          ? (0, _utils.formatWithValidation)(
-              (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
-                typeof url === "object" ? url : (0, _url.parse)(url)
-              )
-            )
-          : url;
+      function resolveHref(currentPath, href) {
+        // we use a dummy base url for relative urls
+        var base = new URL(currentPath, "http://n");
+        var urlAsString =
+          typeof href === "string"
+            ? href
+            : (0, _utils.formatWithValidation)(href);
+        var finalUrl = (0, _normalizeTrailingSlash.normalizeTrailingSlash)(
+          new URL(urlAsString, base)
+        ); // if the origin didn't change, it means we received a relative href
+
+        return finalUrl.origin === base.origin
+          ? finalUrl.href.slice(finalUrl.origin.length)
+          : finalUrl.href;
       }
 
-      function prepareUrlAs(url, as) {
+      function prepareUrlAs(router, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
         return {
-          url: addBasePath(formatUrl(url)),
-          as: as ? addBasePath(formatUrl(as)) : as
+          url: addBasePath(resolveHref(router.pathname, url)),
+          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
         };
       }
 
+      function tryParseRelativeUrl(url) {
+        try {
+          return (0, _parseRelativeUrl.parseRelativeUrl)(url);
+        } catch (err) {
+          if (false) {
+          }
+
+          return null;
+        }
+      }
+
       var manualScrollRestoration = false && false;
 
       function fetchNextData(dataHref, isServerRender, cb) {
@@ -800,24 +732,26 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // But we can simply replace the state with the new changes.
               // Actually, for (1) we don't need to nothing. But it's hard to detect that event.
               // So, doing the following for (1) does no harm.
-              var { pathname, query } = this;
+              var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(pathname),
+                  pathname: addBasePath(_pathname2),
                   query
                 }),
                 (0, _utils.getURL)()
               );
               return;
-            } // Make sure we don't re-render on initial load,
+            }
+
+            var { url, as, options } = e.state;
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(url); // Make sure we don't re-render on initial load,
             // can be caused by navigating back from an external site
 
             if (
-              e.state &&
               this.isSsr &&
-              e.state.as === this.asPath &&
-              (0, _url.parse)(e.state.url).pathname === this.pathname
+              as === this.asPath &&
+              pathname === this.pathname
             ) {
               return;
             } // If the downstream application returns falsy, return.
@@ -827,8 +761,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return;
             }
 
-            var { url, as, options } = e.state;
-
             if (false) {
             }
 
@@ -836,7 +768,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           };
 
           this._getStaticData = dataHref => {
-            var pathname = prepareRoute((0, _url.parse)(dataHref).pathname);
+            var { pathname } = (0, _parseRelativeUrl.parseRelativeUrl)(
+              dataHref
+            );
+            pathname = prepareRoute(pathname);
             return true && this.sdc[pathname]
               ? Promise.resolve(this.sdc[dataHref])
               : fetchNextData(
@@ -977,7 +912,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -996,7 +931,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             arguments.length > 2 && arguments[2] !== undefined
               ? arguments[2]
               : {};
-          ({ url, as } = prepareUrlAs(url, as));
+          ({ url, as } = prepareUrlAs(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
@@ -1030,7 +965,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               return resolve(true);
             }
 
-            var { pathname, query, protocol } = (0, _url.parse)(url, true); // url and as should always be prefixed with basePath by this
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname, searchParams } = parsed;
+            var query = (0, _searchParamsToUrlQuery.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
 
@@ -1039,14 +979,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                   delBasePath(pathname)
                 )
               : pathname;
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return resolve(false);
-            }
-
             var cleanedAs = delBasePath(as); // If asked to change the current URL we should reload the current page
             // (not location.reload() but reload getInitialProps and other Next.js stuffs)
             // We also need to set the method = replaceState always
@@ -1063,7 +995,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             var { shallow = false } = options;
 
             if ((0, _isDynamic.isDynamicRoute)(route)) {
-              var { pathname: asPathname } = (0, _url.parse)(cleanedAs);
+              var { pathname: asPathname } = (0,
+              _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
               var routeRegex = (0, _routeRegex.getRouteRegex)(route);
               var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
                 asPathname
@@ -1366,14 +1299,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               ? arguments[2]
               : {};
           return new Promise((resolve, reject) => {
-            var { pathname, protocol } = (0, _url.parse)(url);
-
-            if (!pathname || protocol) {
-              if (false) {
-              }
-
-              return;
-            } // Prefetch is not supported in development mode because it would trigger on-demand-entries
+            var parsed = tryParseRelativeUrl(url);
+            if (!parsed) return;
+            var { pathname } = parsed; // Prefetch is not supported in development mode because it would trigger on-demand-entries
 
             if (false) {
             }
@@ -1483,7 +1411,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.formatWithValidation = formatWithValidation;
       exports.ST = exports.SP = exports.urlObjectKeys = void 0;
 
-      var _url = __webpack_require__("QmWs");
+      var _formatUrl = __webpack_require__("6D7l");
       /**
        * Utils
        */
@@ -1582,11 +1510,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       ];
       exports.urlObjectKeys = urlObjectKeys;
 
-      function formatWithValidation(url, options) {
+      function formatWithValidation(url) {
         if (false) {
         }
 
-        return (0, _url.format)(url, options);
+        return (0, _formatUrl.formatUrl)(url);
       }
 
       var SP = typeof performance !== "undefined";
@@ -1645,6 +1573,41 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       /***/
     },
 
+    /***/ hS4m: /***/ function(module, exports, __webpack_require__) {
+      "use strict";
+
+      exports.__esModule = true;
+      exports.parseRelativeUrl = parseRelativeUrl;
+      var DUMMY_BASE = new URL("http://n");
+      /**
+       * Parses path-relative urls (e.g. `/hello/world?foo=bar`). If url isn't path-relative
+       * (e.g. `./hello`) then at least base must be.
+       * Absolute urls are rejected.
+       */
+
+      function parseRelativeUrl(url, base) {
+        var resolvedBase = base ? new URL(base, DUMMY_BASE) : DUMMY_BASE;
+        var { pathname, searchParams, search, hash, href, origin } = new URL(
+          url,
+          resolvedBase
+        );
+
+        if (origin !== DUMMY_BASE.origin) {
+          throw new Error("invariant: invalid relative URL");
+        }
+
+        return {
+          pathname,
+          searchParams,
+          search,
+          hash,
+          href: href.slice(DUMMY_BASE.origin.length)
+        };
+      }
+
+      /***/
+    },
+
     /***/ kd2E: /***/ function(module, exports, __webpack_require__) {
       "use strict";
       // Copyright Joyent, Inc. and other Node contributors.
Diff for main-HASH.js
@@ -1482,8 +1482,6 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       exports.__esModule = true;
       exports["default"] = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1492,6 +1490,10 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _escapePathDelimiters = _interopRequireDefault(
         __webpack_require__("fcRV")
       );
@@ -1622,12 +1624,16 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function getDataHref(href, asPath, ssg) {
               var _this2 = this;
 
-              var _ref = (0, _url.parse)(href, true),
+              var _ref = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref.pathname,
-                query = _ref.query,
+                searchParams = _ref.searchParams,
                 search = _ref.search;
 
-              var _ref2 = (0, _url.parse)(asPath),
+              var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+                searchParams
+              );
+
+              var _ref2 = (0, _parseRelativeUrl.parseRelativeUrl)(asPath),
                 asPathname = _ref2.pathname;
 
               var route = normalizeRoute(hrefPathname);
@@ -1712,7 +1718,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
             value: function prefetchData(href, asPath) {
               var _this3 = this;
 
-              var _ref3 = (0, _url.parse)(href, true),
+              var _ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(href),
                 hrefPathname = _ref3.pathname;
 
               var route = normalizeRoute(hrefPathname);
Diff for main-HASH.module.js
@@ -1121,8 +1121,6 @@
       exports.__esModule = true;
       exports.default = void 0;
 
-      var _url = __webpack_require__("QmWs");
-
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
       var _isDynamic = __webpack_require__("/jkW");
@@ -1131,6 +1129,10 @@
 
       var _routeRegex = __webpack_require__("YTqd");
 
+      var _searchParamsToUrlQuery = __webpack_require__("cE6r");
+
+      var _parseRelativeUrl = __webpack_require__("hS4m");
+
       var _escapePathDelimiters = _interopRequireDefault(
         __webpack_require__("fcRV")
       );
@@ -1245,11 +1247,13 @@
          */
 
         getDataHref(href, asPath, ssg) {
-          var { pathname: hrefPathname, query, search } = (0, _url.parse)(
-            href,
-            true
+          var { pathname: hrefPathname, searchParams, search } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
           );
-          var { pathname: asPathname } = (0, _url.parse)(asPath);
+          var { pathname: asPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(asPath);
           var route = normalizeRoute(hrefPathname);
 
           var getHrefForSlug =
@@ -1322,7 +1326,8 @@
          */
 
         prefetchData(href, asPath) {
-          var { pathname: hrefPathname } = (0, _url.parse)(href, true);
+          var { pathname: hrefPathname } = (0,
+          _parseRelativeUrl.parseRelativeUrl)(href);
           var route = normalizeRoute(hrefPathname);
           return this.promisedSsgManifest.then(
             (
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.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/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      href="/_next/static/pages/link-481c9ef0fea508bf4d17.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/pages/link-af971698baef7eb52a5a.js"
+      src="/_next/static/pages/link-384139ace1609fd05ce0.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/pages/link-7ed56a2be20f20a492a2.module.js"
+      src="/_next/static/pages/link-481c9ef0fea508bf4d17.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/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      href="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      href="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/runtime/polyfills-fa968511391ff096b874.js"
     ></script>
     <script
-      src="/_next/static/runtime/main-f521002dc4f0d8e5f7f2.js"
+      src="/_next/static/runtime/main-453f3f97415c9e8e8e2d.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/runtime/main-cfa55ab2fa44e022ecbb.module.js"
+      src="/_next/static/runtime/main-c862fa44db1c1c562f87.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57653bae0c6b697ae7df.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.57d1fe46206a0a6b272c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.81cf701752e54f994ede.module.js"
+      src="/_next/static/chunks/19b7e98f51cc0d86c45d01159bbbfb942bfe49b8.e45f41c352a27ba1912c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js wip-remove-url Change
buildDuration 13.1s 13.1s ⚠️ +34ms
nodeModulesSize 66.4 MB 66.5 MB ⚠️ +15.1 kB

<d
Post job cleanup.
[command]/usr/bin/git version
git version 2.27.0
[command]/usr/bin/git config --local --name-only --get-regexp core.sshCommand
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'core.sshCommand' && git config --local --unset-all 'core.sshCommand' || :
[command]/usr/bin/git config --local --name-only --get-regexp http.https://github.com/.extraheader
http.https://github.com/.extraheader
[command]/usr/bin/git config --local --unset-all http.https://github.com/.extraheader
[command]/usr/bin/git submodule foreach --recursive git config --local --name-only --get-regexp 'http.https://github.com/.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :
Cleaning up orphan processes
Commit: 5439a23

@kodiakhq kodiakhq bot merged commit 3369d67 into vercel:canary Jul 13, 2020
@Janpot Janpot deleted the wip-remove-url branch July 13, 2020 16:13
kodiakhq bot pushed a commit that referenced this pull request Jul 13, 2020
url,
resolvedBase
)
if (origin !== DUMMY_BASE.origin) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Janpot This clause triggers when I'm using the assetPrefix option in production. Is this expected?

Copy link
Contributor Author

@Janpot Janpot Jul 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you using an absolute assetPrefix? Which action triggers this exactly? Do you happen to have a minimal reproduction?

Copy link

@stephanschubert stephanschubert Jul 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's absolute, yes:

assetPrefix: isProd ? "https://d34vhhr1t6sulw.cloudfront.net" : "",

No minimal production but you can see the error here:

  1. Goto https://d34vhhr1t6sulw.cloudfront.net
  2. Open console
  3. Click on "Archiv" link in header

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Janpot Could you take a look at it yet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stephanschubert We are following up at #15188

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants