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

optimize basePath #15710

Closed
wants to merge 21 commits into from
Closed

optimize basePath #15710

wants to merge 21 commits into from

Conversation

Janpot
Copy link
Contributor

@Janpot Janpot commented Jul 30, 2020

move adding of basePath further downstream to allow more code sharing with Link and to do less back and forth url basepath transformations. basepath really should be just handled at the extremities.

@ijjk
Copy link
Member

ijjk commented Jul 30, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 12.7s 12.8s ⚠️ +84ms
nodeModulesSize 65.5 MB 65.5 MB -986 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.171 2.255 ⚠️ +0.08
/ avg req/sec 1151.52 1108.51 ⚠️ -43.01
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.212 1.271 ⚠️ +0.06
/error-in-render avg req/sec 2062.61 1966.31 ⚠️ -96.3
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB 10.2 kB ⚠️ +9 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-935e413..31c4.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +9 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.09 kB -2 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-4b8f4a8..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB -2 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 945 B 945 B
link.html gzip 953 B 951 B -2 B
withRouter.html gzip 940 B 939 B -1 B
Overall change 2.84 kB 2.83 kB -3 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..f9.module.js
@@ -538,7 +538,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -607,12 +607,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -751,7 +752,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (false) {
             }
 
-            this.change("replaceState", url, as, options);
+            this.change(
+              "replaceState",
+              delBasePath(url),
+              delBasePath(as),
+              options
+            );
           }; // represents the current component key
 
           this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
@@ -881,7 +887,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -900,11 +905,14 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserUrl = addBasePath(url);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -922,45 +930,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
-            this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
+            this.changeState(method, browserUrl, browserAs, options);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
@@ -968,7 +966,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -999,35 +997,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
-            this.changeState(method, url, as, options);
+            Router.events.emit("beforeHistoryChange", browserAs);
+            this.changeState(method, browserUrl, browserAs, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
Diff for 677f882d2ed8..dbb170329.js
@@ -669,7 +669,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -738,12 +738,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -895,7 +896,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (false) {
             }
 
-            _this.change("replaceState", url, as, options);
+            _this.change(
+              "replaceState",
+              delBasePath(url),
+              delBasePath(as),
+              options
+            );
           }; // represents the current component key
 
           this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
@@ -1030,10 +1036,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1054,10 +1056,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1067,12 +1065,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserUrl,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
@@ -1094,6 +1096,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserUrl = addBasePath(url);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1110,64 +1122,58 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 15;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
-                              this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
+                              this.changeState(
+                                method,
+                                browserUrl,
+                                browserAs,
+                                options
+                              );
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 15:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 19;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 19:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
+                              );
                               route = (0,
                               _normalizeTrailingSlash.removePathTrailingSlash)(
                                 pathname
@@ -1179,12 +1185,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1195,7 +1201,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1206,7 +1212,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1223,79 +1229,90 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
-                              this.changeState(method, url, as, options);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
+                              this.changeState(
+                                method,
+                                browserUrl,
+                                browserAs,
+                                options
+                              );
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1303,7 +1320,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0ca81720fe845f3d8f3e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.30e0b9acafa9d73fbd3e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0ca81720fe845f3d8f3e.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0ca81720fe845f3d8f3e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.30e0b9acafa9d73fbd3e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0ca81720fe845f3d8f3e.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0ca81720fe845f3d8f3e.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.30e0b9acafa9d73fbd3e.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0ca81720fe845f3d8f3e.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 14.1s 14.2s ⚠️ +67ms
nodeModulesSize 65.5 MB 65.5 MB -986 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-935e413..31c4.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..fe81.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +9 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-4b8f4a8..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.09 kB N/A
Overall change 51.8 kB 51.8 kB -2 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -418 B
routerDirect.js 1.05 MB 1.05 MB -274 B
withRouter.js 1.05 MB 1.05 MB -274 B
Overall change 5.2 MB 5.2 MB -966 B
Commit: fd0a5b6

@ijjk
Copy link
Member

ijjk commented Jul 30, 2020

Failing test suites

Commit: fd0a5b6

test/integration/trailing-slashes/test/index.test.js

  • Trailing slashes > dev mode, trailingSlash: true > /about/?hello=world should client side render /about.js, with router path /about
  • Trailing slashes > production mode, trailingSlash: true > /about/?hello=world should client side render /about.js, with router path /about
Expand output

● Trailing slashes › dev mode, trailingSlash: true › /about/?hello=world should client side render /about.js, with router path /about

expect(received).toBe(expected) // Object.is equality

Expected: "/about"
Received: "/about/"

  61 |           .elementByCss('#router-pathname')
  62 |           .text()
> 63 |         expect(routerPathname).toBe(expectedRouterPath)
     |                                ^
  64 |       } finally {
  65 |         if (browser) await browser.close()
  66 |       }

  at integration/trailing-slashes/test/index.test.js:63:32

● Trailing slashes › production mode, trailingSlash: true › /about/?hello=world should client side render /about.js, with router path /about

expect(received).toBe(expected) // Object.is equality

Expected: "/about"
Received: "/about/"

  61 |           .elementByCss('#router-pathname')
  62 |           .text()
> 63 |         expect(routerPathname).toBe(expectedRouterPath)
     |                                ^
  64 |       } finally {
  65 |         if (browser) await browser.close()
  66 |       }

  at integration/trailing-slashes/test/index.test.js:63:32
      at runMicrotasks (<anonymous>)

@ijjk
Copy link
Member

ijjk commented Jul 30, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 11.6s 11.7s ⚠️ +108ms
nodeModulesSize 65.5 MB 65.5 MB -850 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.062 2.092 ⚠️ +0.03
/ avg req/sec 1212.25 1194.85 ⚠️ -17.4
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.215 1.195 -0.02
/error-in-render avg req/sec 2057.95 2092.34 +34.39
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB 10.2 kB ⚠️ +23 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-935e413..31c4.js gzip 6.76 kB 6.76 kB ⚠️ +1 B
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.9 kB ⚠️ +24 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.09 kB ⚠️ +5 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-4b8f4a8..dule.js gzip 5.84 kB 5.84 kB ⚠️ +3 B
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +8 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 945 B 946 B ⚠️ +1 B
link.html gzip 953 B 951 B -2 B
withRouter.html gzip 940 B 941 B ⚠️ +1 B
Overall change 2.84 kB 2.84 kB

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..f9.module.js
@@ -538,7 +538,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -607,12 +607,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -717,10 +718,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query
                 }),
-                (0, _utils.getURL)()
+                delBasePath((0, _utils.getURL)())
               );
               return;
             }
@@ -779,7 +780,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+            _pathname
+          );
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -800,16 +803,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+            var browserUrl = (0, _utils.getURL)();
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -881,7 +886,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -900,11 +904,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -922,45 +928,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
@@ -968,7 +964,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -999,35 +995,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1058,7 +1054,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              addBasePath(as)
             );
           }
         }
@@ -1177,7 +1173,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         set(route, pathname, query, as, data) {
           this.isFallback = false;
           this.route = route;
-          this.pathname = pathname;
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+            pathname
+          );
           this.query = query;
           this.asPath = as;
           return this.notify(data);
Diff for 677f882d2ed8..dbb170329.js
@@ -669,7 +669,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -738,12 +738,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -855,10 +856,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query: query
                 }),
-                (0, _utils.getURL)()
+                delBasePath((0, _utils.getURL)())
               );
 
               return;
@@ -923,7 +924,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+            _pathname
+          );
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -944,16 +947,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+            var browserUrl = (0, _utils.getURL)();
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -1030,10 +1035,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1054,10 +1055,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1067,12 +1064,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
@@ -1094,6 +1094,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1110,64 +1119,53 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
+                              );
                               route = (0,
                               _normalizeTrailingSlash.removePathTrailingSlash)(
                                 pathname
@@ -1184,7 +1182,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1232,21 +1230,24 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Object.assign(query, routeMatch);
 
                             case 34:
-                              Router.events.emit("routeChangeStart", as);
+                              Router.events.emit("routeChangeStart", browserAs);
                               _context.prev = 35;
                               _context.next = 38;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
                             case 38:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
@@ -1257,7 +1258,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
@@ -1270,7 +1271,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
@@ -1278,7 +1279,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
                             case 53:
@@ -1337,7 +1341,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    addBasePath(as)
                   );
                 }
               }
@@ -1648,7 +1652,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               value: function set(route, pathname, query, as, data) {
                 this.isFallback = false;
                 this.route = route;
-                this.pathname = pathname;
+                this.pathname = (0,
+                _normalizeTrailingSlash.removePathTrailingSlash)(pathname);
                 this.query = query;
                 this.asPath = as;
                 return this.notify(data);
Diff for main-88a4d80..5b.module.js
@@ -243,7 +243,7 @@
           page === "/_error" &&
           hydrateProps &&
           hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === "404"
+          hydrateProps.pageProps.statusCode === 404
         )
       ) {
         asPath = (0, _router2.delBasePath)(asPath);
Diff for main-e647ae2..b3e1da5ee.js
@@ -323,7 +323,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           page === "/_error" &&
           hydrateProps &&
           hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === "404"
+          hydrateProps.pageProps.statusCode === 404
         )
       ) {
         asPath = (0, _router2.delBasePath)(asPath);
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      href="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-e647ae20b32b3e1da5ee.js"
+      src="/_next/static/chunks/main-09c9c57d88bf60213597.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      src="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e52e7da9e62edcbc1897.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      href="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-e647ae20b32b3e1da5ee.js"
+      src="/_next/static/chunks/main-09c9c57d88bf60213597.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      src="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e52e7da9e62edcbc1897.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      href="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-e647ae20b32b3e1da5ee.js"
+      src="/_next/static/chunks/main-09c9c57d88bf60213597.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      src="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e52e7da9e62edcbc1897.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 12.4s 13.4s ⚠️ +1s
nodeModulesSize 65.5 MB 65.5 MB -850 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-935e413..31c4.js gzip 6.76 kB N/A N/A
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..f590.js gzip N/A 10.2 kB N/A
main-88c5dea..200a.js gzip N/A 6.76 kB N/A
Overall change 56.8 kB 56.9 kB ⚠️ +24 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-4b8f4a8..dule.js gzip 5.84 kB N/A N/A
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.09 kB N/A
main-001590a..dule.js gzip N/A 5.84 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +8 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -402 B
routerDirect.js 1.05 MB 1.05 MB -258 B
withRouter.js 1.05 MB 1.05 MB -258 B
Overall change 5.2 MB 5.2 MB -918 B
Commit: aec5b40

@Janpot Janpot marked this pull request as ready for review July 30, 2020 20:16
@ijjk
Copy link
Member

ijjk commented Jul 30, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 13.5s 13.1s -462ms
nodeModulesSize 65.5 MB 65.5 MB -850 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.342 2.339 0
/ avg req/sec 1067.64 1068.94 +1.3
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.309 1.355 ⚠️ +0.05
/error-in-render avg req/sec 1909.57 1845.02 ⚠️ -64.55
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB 10.2 kB ⚠️ +23 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-935e413..31c4.js gzip 6.76 kB 6.76 kB ⚠️ +1 B
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.9 kB ⚠️ +24 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.09 kB ⚠️ +5 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-4b8f4a8..dule.js gzip 5.84 kB 5.84 kB ⚠️ +3 B
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +8 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 945 B 946 B ⚠️ +1 B
link.html gzip 953 B 951 B -2 B
withRouter.html gzip 940 B 941 B ⚠️ +1 B
Overall change 2.84 kB 2.84 kB

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..f9.module.js
@@ -538,7 +538,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -607,12 +607,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -717,10 +718,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query
                 }),
-                (0, _utils.getURL)()
+                delBasePath((0, _utils.getURL)())
               );
               return;
             }
@@ -779,7 +780,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+            _pathname
+          );
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -800,16 +803,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+            var browserUrl = (0, _utils.getURL)();
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -881,7 +886,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -900,11 +904,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -922,45 +928,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
@@ -968,7 +964,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -999,35 +995,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1058,7 +1054,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              addBasePath(as)
             );
           }
         }
@@ -1177,7 +1173,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         set(route, pathname, query, as, data) {
           this.isFallback = false;
           this.route = route;
-          this.pathname = pathname;
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+            pathname
+          );
           this.query = query;
           this.asPath = as;
           return this.notify(data);
Diff for 677f882d2ed8..dbb170329.js
@@ -669,7 +669,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -738,12 +738,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -855,10 +856,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query: query
                 }),
-                (0, _utils.getURL)()
+                delBasePath((0, _utils.getURL)())
               );
 
               return;
@@ -923,7 +924,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+            _pathname
+          );
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -944,16 +947,18 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (true) {
             // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+            var browserUrl = (0, _utils.getURL)();
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -1030,10 +1035,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1054,10 +1055,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1067,12 +1064,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
@@ -1094,6 +1094,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1110,64 +1119,53 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
+                              );
                               route = (0,
                               _normalizeTrailingSlash.removePathTrailingSlash)(
                                 pathname
@@ -1184,7 +1182,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1232,21 +1230,24 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Object.assign(query, routeMatch);
 
                             case 34:
-                              Router.events.emit("routeChangeStart", as);
+                              Router.events.emit("routeChangeStart", browserAs);
                               _context.prev = 35;
                               _context.next = 38;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
                             case 38:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
@@ -1257,7 +1258,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
@@ -1270,7 +1271,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
@@ -1278,7 +1279,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
                             case 53:
@@ -1337,7 +1341,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    addBasePath(as)
                   );
                 }
               }
@@ -1648,7 +1652,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               value: function set(route, pathname, query, as, data) {
                 this.isFallback = false;
                 this.route = route;
-                this.pathname = pathname;
+                this.pathname = (0,
+                _normalizeTrailingSlash.removePathTrailingSlash)(pathname);
                 this.query = query;
                 this.asPath = as;
                 return this.notify(data);
Diff for main-88a4d80..5b.module.js
@@ -243,7 +243,7 @@
           page === "/_error" &&
           hydrateProps &&
           hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === "404"
+          hydrateProps.pageProps.statusCode === 404
         )
       ) {
         asPath = (0, _router2.delBasePath)(asPath);
Diff for main-e647ae2..b3e1da5ee.js
@@ -323,7 +323,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
           page === "/_error" &&
           hydrateProps &&
           hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === "404"
+          hydrateProps.pageProps.statusCode === 404
         )
       ) {
         asPath = (0, _router2.delBasePath)(asPath);
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      href="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-e647ae20b32b3e1da5ee.js"
+      src="/_next/static/chunks/main-09c9c57d88bf60213597.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      src="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e52e7da9e62edcbc1897.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      href="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-e647ae20b32b3e1da5ee.js"
+      src="/_next/static/chunks/main-09c9c57d88bf60213597.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      src="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e52e7da9e62edcbc1897.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      href="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-e647ae20b32b3e1da5ee.js"
+      src="/_next/static/chunks/main-09c9c57d88bf60213597.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-88a4d8003836e3421b5b.module.js"
+      src="/_next/static/chunks/main-fbe7700ee735039eb116.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e52e7da9e62edcbc1897.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.b2af93735f4e8bd7af73.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 14.5s 14.8s ⚠️ +266ms
nodeModulesSize 65.5 MB 65.5 MB -850 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-935e413..31c4.js gzip 6.76 kB N/A N/A
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..f590.js gzip N/A 10.2 kB N/A
main-88c5dea..200a.js gzip N/A 6.76 kB N/A
Overall change 56.8 kB 56.9 kB ⚠️ +24 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-4b8f4a8..dule.js gzip 5.84 kB N/A N/A
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.09 kB N/A
main-001590a..dule.js gzip N/A 5.84 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +8 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -402 B
routerDirect.js 1.05 MB 1.05 MB -258 B
withRouter.js 1.05 MB 1.05 MB -258 B
Overall change 5.2 MB 5.2 MB -918 B
Commit: 9e3d066

@Janpot Janpot marked this pull request as draft July 30, 2020 20:46
@Janpot
Copy link
Contributor Author

Janpot commented Jul 30, 2020

Sry, just thought of something. Gonna have another look at this tomorrow

@Janpot Janpot mentioned this pull request Jul 31, 2020
kodiakhq bot pushed a commit that referenced this pull request Jul 31, 2020
Caught this while reviewing router code for #15710
@ijjk
Copy link
Member

ijjk commented Jul 31, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 12.7s 12.8s ⚠️ +113ms
nodeModulesSize 65.5 MB 65.5 MB -906 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.203 2.289 ⚠️ +0.09
/ avg req/sec 1134.86 1092.41 ⚠️ -42.45
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.241 1.269 ⚠️ +0.03
/error-in-render avg req/sec 2014.62 1970.19 ⚠️ -44.43
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB 10.2 kB ⚠️ +19 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-88c5dea..200a.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +19 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.09 kB ⚠️ +1 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-001590a..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +1 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 947 B 948 B ⚠️ +1 B
link.html gzip 953 B 952 B -1 B
withRouter.html gzip 940 B 942 B ⚠️ +2 B
Overall change 2.84 kB 2.84 kB ⚠️ +2 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..f9.module.js
@@ -538,7 +538,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -607,12 +607,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -751,12 +752,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (false) {
             }
 
-            this.change("replaceState", url, as, options);
-          }; // represents the current component key
+            this.change(
+              "replaceState",
+              delBasePath(url),
+              delBasePath(as),
+              options
+            );
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -779,7 +787,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -881,7 +888,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -900,11 +906,14 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserUrl = addBasePath(url);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -922,53 +931,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
-            this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
+            this.changeState(method, browserUrl, browserAs, options);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -999,35 +999,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
-            this.changeState(method, url, as, options);
+            Router.events.emit("beforeHistoryChange", browserAs);
+            this.changeState(method, browserUrl, browserAs, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
Diff for 677f882d2ed8..dbb170329.js
@@ -669,7 +669,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -738,12 +738,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -895,12 +896,19 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (false) {
             }
 
-            _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+            _this.change(
+              "replaceState",
+              delBasePath(url),
+              delBasePath(as),
+              options
+            );
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -923,7 +931,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -1030,10 +1037,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1054,10 +1057,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1067,17 +1066,21 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserUrl,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1094,6 +1097,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserUrl = addBasePath(url);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1110,67 +1123,62 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 15;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
-                              this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
+                              this.changeState(
+                                method,
+                                browserUrl,
+                                browserAs,
+                                options
+                              );
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 15:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 19;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 19:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1179,12 +1187,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 36;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1195,7 +1203,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 35;
                                 break;
                               }
 
@@ -1206,7 +1214,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 33;
                                 break;
                               }
 
@@ -1223,79 +1231,90 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 33:
+                              _context.next = 36;
                               break;
 
-                            case 33:
+                            case 35:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 36:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 37;
+                              _context.next = 40;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 40:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
-                              this.changeState(method, url, as, options);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
+                              this.changeState(
+                                method,
+                                browserUrl,
+                                browserAs,
+                                options
+                              );
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 47;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 47:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 50;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 50:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 55:
+                              _context.prev = 55;
+                              _context.t0 = _context["catch"](37);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 59;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 59:
                               throw _context.t0;
 
-                            case 58:
+                            case 60:
                             case "end":
                               return _context.stop();
                           }
@@ -1303,7 +1322,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[37, 55]]
                     );
                   })
                 );
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.347db8ad81fc4a6a7c6c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e7d518a815e770f253ee.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.347db8ad81fc4a6a7c6c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.347db8ad81fc4a6a7c6c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e7d518a815e770f253ee.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.347db8ad81fc4a6a7c6c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.347db8ad81fc4a6a7c6c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.289defeb577dbb170329.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.e7d518a815e770f253ee.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.277a28e61ddacb493af9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.347db8ad81fc4a6a7c6c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 14.5s 14.2s -265ms
nodeModulesSize 65.5 MB 65.5 MB -906 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..b7a9.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-88c5dea..200a.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..0802.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +19 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-001590a..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.09 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +1 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -389 B
routerDirect.js 1.05 MB 1.05 MB -245 B
withRouter.js 1.05 MB 1.05 MB -245 B
Overall change 5.2 MB 5.2 MB -879 B
Commit: 15bcf71

@ijjk
Copy link
Member

ijjk commented Jul 31, 2020

Failing test suites

Commit: dae4367

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.10000000000000142

  105 |       expect(err404FirstLoad.endsWith('kB')).toBe(true)
  106 | 
> 107 |       expect(parseFloat(sharedByAll) - 59.3).toBeLessThanOrEqual(0)
      |                                              ^
  108 |       expect(sharedByAll.endsWith('kB')).toBe(true)
  109 | 
  110 |       if (_appSize.endsWith('kB')) {

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

@ijjk
Copy link
Member

ijjk commented Jul 31, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 12.8s 12.6s -206ms
nodeModulesSize 65.5 MB 65.5 MB -228 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.237 2.187 -0.05
/ avg req/sec 1117.79 1143.31 +25.52
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.203 1.204 0
/error-in-render avg req/sec 2077.77 2076.31 ⚠️ -1.46
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB 10.2 kB ⚠️ +36 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.9 kB ⚠️ +36 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.1 kB ⚠️ +12 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +12 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 944 B 944 B
link.html gzip 951 B 949 B -2 B
withRouter.html gzip 939 B 937 B -2 B
Overall change 2.83 kB 2.83 kB -4 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..a64f02486.js
@@ -669,7 +669,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -738,12 +738,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -849,17 +850,22 @@ 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 _pathname2 = _this.pathname,
-                query = _this.query;
-
-              _this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query: query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+
+              if (browserUrl.startsWith(basePath)) {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                var _pathname2 = _this.pathname,
+                  query = _this.query;
+
+                _this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query: query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              }
 
               return;
             }
@@ -893,11 +899,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -920,7 +928,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -939,18 +946,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -1027,10 +1036,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1051,10 +1056,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1064,17 +1065,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1091,6 +1095,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1107,67 +1120,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1176,12 +1179,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1192,7 +1195,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1203,7 +1206,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1220,79 +1223,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1300,7 +1309,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1323,7 +1332,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 if (false) {
                 }
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                var browserAs = addBasePath(as);
+
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1334,7 +1348,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for 677f882d2ed8..e4.module.js
@@ -538,7 +538,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -607,12 +607,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -713,15 +714,21 @@ 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: _pathname2, query } = this;
-              this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+
+              if (browserUrl.startsWith(basePath)) {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                var { pathname: _pathname2, query } = this;
+                this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              }
+
               return;
             }
 
@@ -749,11 +756,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -776,7 +785,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -795,18 +803,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -878,7 +888,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -897,11 +906,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -919,53 +930,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -996,35 +998,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1044,7 +1046,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (false) {
           }
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          var browserAs = addBasePath(as);
+
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1055,7 +1059,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55ccdf9ef98dbb003620.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55ccdf9ef98dbb003620.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55ccdf9ef98dbb003620.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 15.1s 13.9s -1.2s
nodeModulesSize 65.5 MB 65.5 MB -228 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..9eaa.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.9 kB ⚠️ +36 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.1 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +12 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -236 B
routerDirect.js 1.05 MB 1.05 MB -92 B
withRouter.js 1.05 MB 1.05 MB -92 B
Overall change 5.2 MB 5.2 MB -420 B
Commit: dae4367

@ijjk
Copy link
Member

ijjk commented Jul 31, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 10.6s 10.6s ⚠️ +22ms
nodeModulesSize 65.5 MB 65.5 MB -228 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 1.884 1.963 ⚠️ +0.08
/ avg req/sec 1326.89 1273.26 ⚠️ -53.63
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.052 1.044 -0.01
/error-in-render avg req/sec 2376.52 2394.69 +18.17
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB 10.2 kB ⚠️ +36 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.9 kB ⚠️ +36 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.1 kB ⚠️ +12 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +12 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 944 B 944 B
link.html gzip 951 B 949 B -2 B
withRouter.html gzip 939 B 937 B -2 B
Overall change 2.83 kB 2.83 kB -4 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..a64f02486.js
@@ -669,7 +669,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -738,12 +738,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -849,17 +850,22 @@ 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 _pathname2 = _this.pathname,
-                query = _this.query;
-
-              _this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query: query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+
+              if (browserUrl.startsWith(basePath)) {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                var _pathname2 = _this.pathname,
+                  query = _this.query;
+
+                _this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query: query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              }
 
               return;
             }
@@ -893,11 +899,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -920,7 +928,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -939,18 +946,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -1027,10 +1036,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1051,10 +1056,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1064,17 +1065,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1091,6 +1095,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1107,67 +1120,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1176,12 +1179,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1192,7 +1195,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1203,7 +1206,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1220,79 +1223,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1300,7 +1309,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1323,7 +1332,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 if (false) {
                 }
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                var browserAs = addBasePath(as);
+
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1334,7 +1348,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for 677f882d2ed8..e4.module.js
@@ -538,7 +538,7 @@ 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.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -607,12 +607,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -713,15 +714,21 @@ 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: _pathname2, query } = this;
-              this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+
+              if (browserUrl.startsWith(basePath)) {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                var { pathname: _pathname2, query } = this;
+                this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              }
+
               return;
             }
 
@@ -749,11 +756,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -776,7 +785,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -795,18 +803,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -878,7 +888,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -897,11 +906,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -919,53 +930,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -996,35 +998,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1044,7 +1046,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (false) {
           }
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          var browserAs = addBasePath(as);
+
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1055,7 +1059,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55ccdf9ef98dbb003620.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55ccdf9ef98dbb003620.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.55ccdf9ef98dbb003620.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.0173b0c24e9dd7868d5c.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 11.7s 10.7s -978ms
nodeModulesSize 65.5 MB 65.5 MB -228 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB 6.76 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..9eaa.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.9 kB ⚠️ +36 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB 5.84 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.1 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +12 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -236 B
routerDirect.js 1.05 MB 1.05 MB -92 B
withRouter.js 1.05 MB 1.05 MB -92 B
Overall change 5.2 MB 5.2 MB -420 B
Commit: e47ce6f

@ijjk
Copy link
Member

ijjk commented Jul 31, 2020

Failing test suites

Commit: e47ce6f

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.10000000000000142

  105 |       expect(err404FirstLoad.endsWith('kB')).toBe(true)
  106 | 
> 107 |       expect(parseFloat(sharedByAll) - 59.3).toBeLessThanOrEqual(0)
      |                                              ^
  108 |       expect(sharedByAll.endsWith('kB')).toBe(true)
  109 | 
  110 |       if (_appSize.endsWith('kB')) {

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

@ijjk
Copy link
Member

ijjk commented Jul 31, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 12.3s 12.4s ⚠️ +88ms
nodeModulesSize 65.5 MB 65.5 MB -430 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.179 2.192 ⚠️ +0.01
/ avg req/sec 1147.49 1140.29 ⚠️ -7.2
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.208 1.19 -0.02
/error-in-render avg req/sec 2068.71 2100.45 +31.74
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB 10.2 kB ⚠️ +47 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB 6.73 kB -28 B
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +19 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.11 kB ⚠️ +23 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB 5.81 kB -27 B
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB -4 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 944 B 945 B ⚠️ +1 B
link.html gzip 951 B 950 B -1 B
withRouter.html gzip 939 B 937 B -2 B
Overall change 2.83 kB 2.83 kB -2 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..a64f02486.js
@@ -669,8 +669,8 @@ 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;
+      exports.prepareUrlAs = prepareUrlAs;
+      exports["default"] = exports.basePath = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
@@ -699,6 +699,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       // tslint:disable:no-console
 
       var basePath = false || "";
+      exports.basePath = basePath;
 
       function buildCancellationError() {
         return Object.assign(new Error("Route Cancelled"), {
@@ -738,12 +739,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -849,17 +851,22 @@ 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 _pathname2 = _this.pathname,
-                query = _this.query;
-
-              _this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query: query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+
+              if (browserUrl.startsWith(basePath)) {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                var _pathname2 = _this.pathname,
+                  query = _this.query;
+
+                _this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query: query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              }
 
               return;
             }
@@ -893,11 +900,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -920,7 +929,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -939,18 +947,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -1027,10 +1037,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1051,10 +1057,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1064,17 +1066,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1091,6 +1096,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1107,67 +1121,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1176,12 +1180,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1192,7 +1196,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1203,7 +1207,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1220,79 +1224,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1300,7 +1310,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1323,7 +1333,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 if (false) {
                 }
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                var browserAs = addBasePath(as);
+
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1334,7 +1349,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for 677f882d2ed8..e4.module.js
@@ -538,8 +538,8 @@ 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;
+      exports.prepareUrlAs = prepareUrlAs;
+      exports.default = exports.basePath = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
 
@@ -568,6 +568,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       // tslint:disable:no-console
 
       var basePath = false || "";
+      exports.basePath = basePath;
 
       function buildCancellationError() {
         return Object.assign(new Error("Route Cancelled"), {
@@ -607,12 +608,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -713,15 +715,21 @@ 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: _pathname2, query } = this;
-              this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+
+              if (browserUrl.startsWith(basePath)) {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                var { pathname: _pathname2, query } = this;
+                this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              }
+
               return;
             }
 
@@ -749,11 +757,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -776,7 +786,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -795,18 +804,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && browserUrl.startsWith(basePath)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -878,7 +889,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -897,11 +907,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -919,53 +931,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -996,35 +999,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1044,7 +1047,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (false) {
           }
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          var browserAs = addBasePath(as);
+
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1055,7 +1060,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for main-092ccd6..1a29504b9.js
@@ -317,15 +317,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       });
       var asPath = (0, _utils.getURL)(); // make sure not to attempt stripping basePath for 404s
 
-      if (
-        page !== "/404" &&
-        !(
-          page === "/_error" &&
-          hydrateProps &&
-          hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === 404
-        )
-      ) {
+      if (asPath.startsWith(_router2.basePath)) {
         asPath = (0, _router2.delBasePath)(asPath);
       }
Diff for main-62a1247..37.module.js
@@ -237,15 +237,7 @@
       });
       var asPath = (0, _utils.getURL)(); // make sure not to attempt stripping basePath for 404s
 
-      if (
-        page !== "/404" &&
-        !(
-          page === "/_error" &&
-          hydrateProps &&
-          hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === 404
-        )
-      ) {
+      if (asPath.startsWith(_router2.basePath)) {
         asPath = (0, _router2.delBasePath)(asPath);
       }
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      href="/_next/static/chunks/main-92b4628e3197019fb168.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.69ec7bf314221c539123.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-092ccd6c8111a29504b9.js"
+      src="/_next/static/chunks/main-d46b2ab6c46e638efde6.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      src="/_next/static/chunks/main-92b4628e3197019fb168.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7fe09bfec0b82a47d7d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.69ec7bf314221c539123.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      href="/_next/static/chunks/main-92b4628e3197019fb168.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.69ec7bf314221c539123.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-092ccd6c8111a29504b9.js"
+      src="/_next/static/chunks/main-d46b2ab6c46e638efde6.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      src="/_next/static/chunks/main-92b4628e3197019fb168.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7fe09bfec0b82a47d7d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.69ec7bf314221c539123.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      href="/_next/static/chunks/main-92b4628e3197019fb168.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.69ec7bf314221c539123.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-092ccd6c8111a29504b9.js"
+      src="/_next/static/chunks/main-d46b2ab6c46e638efde6.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      src="/_next/static/chunks/main-92b4628e3197019fb168.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.7fe09bfec0b82a47d7d3.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.69ec7bf314221c539123.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 14.2s 13.6s -609ms
nodeModulesSize 65.5 MB 65.5 MB -430 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB N/A N/A
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..1d02.js gzip N/A 10.2 kB N/A
main-5a89394..a87a.js gzip N/A 6.73 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +19 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB N/A N/A
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.11 kB N/A
main-ec084ca..dule.js gzip N/A 5.81 kB N/A
Overall change 51.8 kB 51.8 kB -4 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -188 B
routerDirect.js 1.05 MB 1.05 MB -44 B
withRouter.js 1.05 MB 1.05 MB -44 B
Overall change 5.2 MB 5.2 MB -276 B
Commit: acaedb3

@ijjk
Copy link
Member

ijjk commented Jul 31, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 14.4s 14.5s ⚠️ +7ms
nodeModulesSize 65.5 MB 65.5 MB ⚠️ +117 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.657 2.688 ⚠️ +0.03
/ avg req/sec 940.88 930.13 ⚠️ -10.75
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.609 1.622 ⚠️ +0.01
/error-in-render avg req/sec 1554.04 1541.52 ⚠️ -12.52
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB 10.2 kB ⚠️ +67 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB 6.73 kB -33 B
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.9 kB ⚠️ +34 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB 6.14 kB ⚠️ +50 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB 5.81 kB -31 B
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +19 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 944 B 945 B ⚠️ +1 B
link.html gzip 951 B 949 B -2 B
withRouter.html gzip 939 B 937 B -2 B
Overall change 2.83 kB 2.83 kB -3 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..a64f02486.js
@@ -667,9 +667,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       var _createClass = __webpack_require__("W8MJ");
 
       exports.__esModule = true;
+      exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -706,6 +707,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function hasBasePath(path) {
+        return path === basePath || path.startsWith(basePath + "/");
+      }
+
       function addBasePath(path) {
         return basePath
           ? path === "/"
@@ -738,12 +743,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -849,17 +855,25 @@ 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 _pathname2 = _this.pathname,
-                query = _this.query;
-
-              _this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query: query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+              console.log(document.location.href, e);
+
+              if (hasBasePath(browserUrl)) {
+                var _pathname2 = _this.pathname,
+                  query = _this.query;
+
+                _this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query: query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              } else {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                window.location.reload();
+              }
 
               return;
             }
@@ -893,11 +907,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -920,7 +936,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -939,18 +954,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && hasBasePath(browserUrl)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -1027,10 +1044,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1051,10 +1064,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1064,17 +1073,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1091,6 +1103,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1107,67 +1128,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = delBasePath(as);
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1176,12 +1187,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1192,7 +1203,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1203,7 +1214,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1220,79 +1231,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1300,7 +1317,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1323,7 +1340,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 if (false) {
                 }
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                var browserAs = addBasePath(as);
+
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1334,7 +1356,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for 677f882d2ed8..e4.module.js
@@ -536,9 +536,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       "use strict";
 
       exports.__esModule = true;
+      exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -575,6 +576,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
         });
       }
 
+      function hasBasePath(path) {
+        return path === basePath || path.startsWith(basePath + "/");
+      }
+
       function addBasePath(path) {
         return basePath
           ? path === "/"
@@ -607,12 +612,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -713,15 +719,24 @@ 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: _pathname2, query } = this;
-              this.changeState(
-                "replaceState",
-                (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
-                  query
-                }),
-                (0, _utils.getURL)()
-              );
+              var browserUrl = (0, _utils.getURL)();
+              console.log(document.location.href, e);
+
+              if (hasBasePath(browserUrl)) {
+                var { pathname: _pathname2, query } = this;
+                this.changeState(
+                  "replaceState",
+                  (0, _utils.formatWithValidation)({
+                    pathname: _pathname2,
+                    query
+                  }),
+                  delBasePath(browserUrl)
+                );
+              } else {
+                // if it doesn't start with the basePath, it's to be treated as an external url
+                window.location.reload();
+              }
+
               return;
             }
 
@@ -749,11 +764,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -776,7 +793,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -795,18 +811,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
-            if (_as.substr(0, 2) !== "//") {
+
+            if (_as.substr(0, 2) !== "//" && hasBasePath(browserUrl)) {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                delBasePath(browserUrl)
               );
             }
 
@@ -878,7 +896,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -897,11 +914,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -919,53 +938,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = delBasePath(as);
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -996,35 +1006,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1044,7 +1054,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           if (false) {
           }
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          var browserAs = addBasePath(as);
+
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1055,7 +1067,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for main-092ccd6..1a29504b9.js
@@ -317,15 +317,7 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
       });
       var asPath = (0, _utils.getURL)(); // make sure not to attempt stripping basePath for 404s
 
-      if (
-        page !== "/404" &&
-        !(
-          page === "/_error" &&
-          hydrateProps &&
-          hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === 404
-        )
-      ) {
+      if ((0, _router2.hasBasePath)(asPath)) {
         asPath = (0, _router2.delBasePath)(asPath);
       }
Diff for main-62a1247..37.module.js
@@ -237,15 +237,7 @@
       });
       var asPath = (0, _utils.getURL)(); // make sure not to attempt stripping basePath for 404s
 
-      if (
-        page !== "/404" &&
-        !(
-          page === "/_error" &&
-          hydrateProps &&
-          hydrateProps.pageProps &&
-          hydrateProps.pageProps.statusCode === 404
-        )
-      ) {
+      if ((0, _router2.hasBasePath)(asPath)) {
         asPath = (0, _router2.delBasePath)(asPath);
       }
Diff for index.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      href="/_next/static/chunks/main-63a645b327ebfc44d4e0.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0d98cf2800bcb302499.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-092ccd6c8111a29504b9.js"
+      src="/_next/static/chunks/main-11db2adbacdc8afcd350.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      src="/_next/static/chunks/main-63a645b327ebfc44d4e0.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.04429964ea9491c457ae.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0d98cf2800bcb302499.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      href="/_next/static/chunks/main-63a645b327ebfc44d4e0.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0d98cf2800bcb302499.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -86,13 +86,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-092ccd6c8111a29504b9.js"
+      src="/_next/static/chunks/main-11db2adbacdc8afcd350.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      src="/_next/static/chunks/main-63a645b327ebfc44d4e0.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.04429964ea9491c457ae.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0d98cf2800bcb302499.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -6,7 +6,7 @@
     <meta name="next-head-count" content="2" />
     <link
       rel="preload"
-      href="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      href="/_next/static/chunks/main-63a645b327ebfc44d4e0.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0d98cf2800bcb302499.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -81,13 +81,13 @@
       src="/_next/static/chunks/polyfills-cdbbd579644400b29b58.js"
     ></script>
     <script
-      src="/_next/static/chunks/main-092ccd6c8111a29504b9.js"
+      src="/_next/static/chunks/main-11db2adbacdc8afcd350.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/main-62a124753b6705b60b37.module.js"
+      src="/_next/static/chunks/main-63a645b327ebfc44d4e0.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.41d5d7ded3aa64f02486.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.04429964ea9491c457ae.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.ef6cc8889408a3d818e4.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.a0d98cf2800bcb302499.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 16.3s 16.1s -181ms
nodeModulesSize 65.5 MB 65.5 MB ⚠️ +117 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..9e81.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-8dccf8c..edef.js gzip 6.76 kB N/A N/A
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..dde5.js gzip N/A 10.2 kB N/A
main-06588f2..f65e.js gzip N/A 6.73 kB N/A
Overall change 56.8 kB 56.9 kB ⚠️ +34 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.09 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-85e7a5d..dule.js gzip 5.84 kB N/A N/A
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.14 kB N/A
main-62e1f09..dule.js gzip N/A 5.81 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +19 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -13 B
routerDirect.js 1.05 MB 1.05 MB ⚠️ +131 B
withRouter.js 1.05 MB 1.05 MB ⚠️ +131 B
Overall change 5.2 MB 5.2 MB ⚠️ +249 B
Commit: 80f3ada

@Janpot Janpot marked this pull request as ready for review July 31, 2020 22:21
@Janpot Janpot marked this pull request as draft August 1, 2020 01:56
@ijjk
Copy link
Member

ijjk commented Aug 1, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 13.4s 12.1s -1.3s
nodeModulesSize 65.5 MB 65.5 MB -341 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.489 2.227 -0.26
/ avg req/sec 1004.54 1122.58 +118.04
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.402 1.323 -0.08
/error-in-render avg req/sec 1782.73 1889.38 +106.65
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..70d8.js gzip 10.2 kB 10.2 kB ⚠️ +29 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +29 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.12 kB 6.12 kB ⚠️ +5 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +5 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 948 B 946 B -2 B
link.html gzip 953 B 953 B
withRouter.html gzip 940 B 940 B
Overall change 2.84 kB 2.84 kB -2 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..05.module.js
@@ -539,7 +539,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -612,12 +612,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -718,14 +719,18 @@ 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 browserUrl = (0, _utils.getURL)();
               var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
               return;
             }
@@ -754,11 +759,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -781,7 +788,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -800,18 +806,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
+
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
             }
 
@@ -883,7 +894,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -902,11 +912,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -924,53 +936,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1001,35 +1004,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1047,9 +1050,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
 
           if (false) {
-          }
+          } // _b is an internal option that indicates whether the basePath needs to be
+          // added. Defaults to true
+
+          var browserAs = options._b === false ? as : addBasePath(as);
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1060,7 +1066,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for 677f882d2ed8..2ad5ed26c.js
@@ -670,7 +670,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -743,12 +743,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -854,16 +855,20 @@ 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 browserUrl = (0, _utils.getURL)();
               var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query: query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
 
               return;
@@ -898,11 +903,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -925,7 +932,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -944,18 +950,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
+
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
             }
 
@@ -1032,10 +1043,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1056,10 +1063,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1069,17 +1072,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1096,6 +1102,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1112,69 +1127,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = hasBasePath(as)
-                                ? delBasePath(as)
-                                : as;
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1183,12 +1186,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1199,7 +1202,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1210,7 +1213,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1227,79 +1230,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1307,7 +1316,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1328,9 +1337,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     : {};
 
                 if (false) {
-                }
+                } // _b is an internal option that indicates whether the basePath needs to be
+                // added. Defaults to true
+
+                var browserAs = options._b === false ? as : addBasePath(as);
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1341,7 +1356,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d0465aed1d7b5d4ce09f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d0465aed1d7b5d4ce09f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d0465aed1d7b5d4ce09f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 13.1s 12.9s -276ms
nodeModulesSize 65.5 MB 65.5 MB -341 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..70d8.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..1347.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +29 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.12 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.12 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +5 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -268 B
routerDirect.js 1.05 MB 1.05 MB -124 B
withRouter.js 1.05 MB 1.05 MB -124 B
Overall change 5.2 MB 5.2 MB -516 B
Commit: 441df92

@ijjk
Copy link
Member

ijjk commented Aug 1, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 12.3s 12.3s ⚠️ +21ms
nodeModulesSize 65.5 MB 65.5 MB -341 B
Page Load Tests Overall decrease ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.126 2.19 ⚠️ +0.06
/ avg req/sec 1175.88 1141.46 ⚠️ -34.42
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.213 1.215 0
/error-in-render avg req/sec 2061.23 2057.8 ⚠️ -3.43
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..70d8.js gzip 10.2 kB 10.2 kB ⚠️ +29 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +29 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.12 kB 6.12 kB ⚠️ +5 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB ⚠️ +5 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 948 B 946 B -2 B
link.html gzip 953 B 953 B
withRouter.html gzip 940 B 940 B
Overall change 2.84 kB 2.84 kB -2 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..05.module.js
@@ -539,7 +539,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -612,12 +612,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -718,14 +719,18 @@ 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 browserUrl = (0, _utils.getURL)();
               var { pathname: _pathname2, query } = this;
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
               return;
             }
@@ -754,11 +759,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -781,7 +788,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -800,18 +806,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
+
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
             }
 
@@ -883,7 +894,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -902,11 +912,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -924,53 +936,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1001,35 +1004,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1047,9 +1050,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
 
           if (false) {
-          }
+          } // _b is an internal option that indicates whether the basePath needs to be
+          // added. Defaults to true
+
+          var browserAs = options._b === false ? as : addBasePath(as);
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1060,7 +1066,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for 677f882d2ed8..2ad5ed26c.js
@@ -670,7 +670,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -743,12 +743,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -854,16 +855,20 @@ 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 browserUrl = (0, _utils.getURL)();
               var _pathname2 = _this.pathname,
                 query = _this.query;
 
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query: query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
 
               return;
@@ -898,11 +903,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -925,7 +932,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -944,18 +950,23 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           this.isFallback = isFallback;
 
           if (true) {
-            // make sure "as" doesn't start with double slashes or else it can
+            var browserUrl = (0, _utils.getURL)(); // make sure "as" doesn't start with double slashes or else it can
             // throw an error as it's considered invalid
+
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                browserUrl,
+                {
+                  _b: false
+                }
               );
             }
 
@@ -1032,10 +1043,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1056,10 +1063,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1069,17 +1072,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1096,6 +1102,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1112,69 +1127,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = hasBasePath(as)
-                                ? delBasePath(as)
-                                : as;
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1183,12 +1186,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1199,7 +1202,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1210,7 +1213,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1227,79 +1230,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1307,7 +1316,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1328,9 +1337,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     : {};
 
                 if (false) {
-                }
+                } // _b is an internal option that indicates whether the basePath needs to be
+                // added. Defaults to true
+
+                var browserAs = options._b === false ? as : addBasePath(as);
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1341,7 +1356,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d0465aed1d7b5d4ce09f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d0465aed1d7b5d4ce09f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d0465aed1d7b5d4ce09f.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.28d53a564f7c21e173a9.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 13.5s 13.2s -286ms
nodeModulesSize 65.5 MB 65.5 MB -341 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..70d8.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..1347.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +29 B
Client Bundles (main, webpack, commons) Modern Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.12 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.12 kB N/A
Overall change 51.8 kB 51.8 kB ⚠️ +5 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -268 B
routerDirect.js 1.05 MB 1.05 MB -124 B
withRouter.js 1.05 MB 1.05 MB -124 B
Overall change 5.2 MB 5.2 MB -516 B
Commit: 19ac04c

@ijjk
Copy link
Member

ijjk commented Aug 1, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 12.1s 12.2s ⚠️ +165ms
nodeModulesSize 65.5 MB 65.5 MB -554 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.144 2.164 ⚠️ +0.02
/ avg req/sec 1165.97 1155.19 ⚠️ -10.78
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.212 1.202 -0.01
/error-in-render avg req/sec 2063.38 2079.46 +16.08
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..70d8.js gzip 10.2 kB 10.2 kB ⚠️ +16 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +16 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.12 kB 6.11 kB -11 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB -11 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 948 B 947 B -1 B
link.html gzip 953 B 952 B -1 B
withRouter.html gzip 940 B 940 B
Overall change 2.84 kB 2.84 kB -2 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..05.module.js
@@ -539,7 +539,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -612,12 +612,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -722,10 +723,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
               return;
             }
@@ -754,11 +758,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -781,7 +787,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -805,13 +810,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
             }
 
@@ -883,7 +892,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -902,11 +910,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -924,53 +934,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1001,35 +1002,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1047,9 +1048,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
 
           if (false) {
-          }
+          } // _b is an internal option that indicates whether the basePath needs to be
+          // added. Defaults to true
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          var browserAs = options._b === false ? as : addBasePath(as);
+
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1060,7 +1064,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for 677f882d2ed8..2ad5ed26c.js
@@ -670,7 +670,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -743,12 +743,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -860,10 +861,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query: query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
 
               return;
@@ -898,11 +902,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -925,7 +931,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -949,13 +954,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
             }
 
@@ -1032,10 +1041,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1056,10 +1061,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1069,17 +1070,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1096,6 +1100,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1112,69 +1125,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = hasBasePath(as)
-                                ? delBasePath(as)
-                                : as;
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1183,12 +1184,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1199,7 +1200,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1210,7 +1211,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1227,79 +1228,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1307,7 +1314,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1328,9 +1335,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     : {};
 
                 if (false) {
-                }
+                } // _b is an internal option that indicates whether the basePath needs to be
+                // added. Defaults to true
+
+                var browserAs = options._b === false ? as : addBasePath(as);
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1341,7 +1354,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.cf96b4846435eae765ab.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6022e6c1c284455db081.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.cf96b4846435eae765ab.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.cf96b4846435eae765ab.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6022e6c1c284455db081.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.cf96b4846435eae765ab.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.cf96b4846435eae765ab.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.d37adacf5052ad5ed26c.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.6022e6c1c284455db081.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.4e14fd48cc5b066cb405.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.cf96b4846435eae765ab.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 13.8s 13.8s ⚠️ +29ms
nodeModulesSize 65.5 MB 65.5 MB -554 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..70d8.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..7c15.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +16 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.12 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.11 kB N/A
Overall change 51.8 kB 51.8 kB -11 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -307 B
routerDirect.js 1.05 MB 1.05 MB -163 B
withRouter.js 1.05 MB 1.05 MB -163 B
Overall change 5.2 MB 5.2 MB -633 B
Commit: 823b0fc

@ijjk
Copy link
Member

ijjk commented Aug 1, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 13.4s 13.5s ⚠️ +140ms
nodeModulesSize 65.5 MB 65.5 MB -536 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.496 2.432 -0.06
/ avg req/sec 1001.42 1028.16 +26.74
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.579 1.49 -0.09
/error-in-render avg req/sec 1583.09 1677.89 +94.8
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..39a4.js gzip 10.2 kB 10.2 kB ⚠️ +16 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +16 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.13 kB 6.12 kB -10 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB -10 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 946 B 946 B
link.html gzip 952 B 950 B -2 B
withRouter.html gzip 939 B 938 B -1 B
Overall change 2.84 kB 2.83 kB -3 B

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..a9.module.js
@@ -539,7 +539,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -612,12 +612,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -724,10 +725,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
               return;
             }
@@ -754,11 +758,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -781,7 +787,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -805,13 +810,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
             }
 
@@ -883,7 +892,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -902,11 +910,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -924,53 +934,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1001,35 +1002,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1047,9 +1048,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
 
           if (false) {
-          }
+          } // _b is an internal option that indicates whether the basePath needs to be
+          // added. Defaults to true
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          var browserAs = options._b === false ? as : addBasePath(as);
+
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1060,7 +1064,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for 677f882d2ed8..7f15aafe7.js
@@ -670,7 +670,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -743,12 +743,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -862,10 +863,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query: query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
 
               return;
@@ -897,11 +901,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -924,7 +930,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -948,13 +953,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             if (_as.substr(0, 2) !== "//") {
               // in order for `e.state` to work on the `onpopstate` event
               // we have to register the initial route upon initialization
+              // if it doesn't start with the basePath, it's to be treated as an external url
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
             }
 
@@ -1031,10 +1040,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1055,10 +1060,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1068,17 +1069,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1095,6 +1099,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1111,69 +1124,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = hasBasePath(as)
-                                ? delBasePath(as)
-                                : as;
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1182,12 +1183,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1198,7 +1199,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1209,7 +1210,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1226,79 +1227,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1306,7 +1313,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1327,9 +1334,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     : {};
 
                 if (false) {
-                }
+                } // _b is an internal option that indicates whether the basePath needs to be
+                // added. Defaults to true
+
+                var browserAs = options._b === false ? as : addBasePath(as);
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1340,7 +1353,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2a34d0e3c2e664d9cd89.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f620cea45847f15aafe7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.1683911e3c8b42700530.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2a34d0e3c2e664d9cd89.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2a34d0e3c2e664d9cd89.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f620cea45847f15aafe7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.1683911e3c8b42700530.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2a34d0e3c2e664d9cd89.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2a34d0e3c2e664d9cd89.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f620cea45847f15aafe7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.1683911e3c8b42700530.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2a34d0e3c2e664d9cd89.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 15s 15.1s ⚠️ +77ms
nodeModulesSize 65.5 MB 65.5 MB -536 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..39a4.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..89e1.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +16 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.13 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.12 kB N/A
Overall change 51.8 kB 51.8 kB -10 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -307 B
routerDirect.js 1.05 MB 1.05 MB -163 B
withRouter.js 1.05 MB 1.05 MB -163 B
Overall change 5.2 MB 5.2 MB -633 B
Commit: 43c9f6a

@ijjk
Copy link
Member

ijjk commented Aug 2, 2020

Stats from current PR

Default Server Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 11.1s 11s -36ms
nodeModulesSize 65.5 MB 65.5 MB -756 B
Page Load Tests Overall increase ✓
vercel/next.js canary Janpot/next.js basePathz Change
/ failed reqs 0 0
/ total time (seconds) 2.003 1.988 -0.02
/ avg req/sec 1248.29 1257.83 +9.54
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.071 1.066 0
/error-in-render avg req/sec 2334.3 2345.35 +11.05
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..39a4.js gzip 10.2 kB 10.2 kB ⚠️ +16 B
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
Overall change 56.8 kB 56.8 kB ⚠️ +16 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.13 kB 6.12 kB -10 B
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
Overall change 51.8 kB 51.8 kB -10 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB 1.28 kB -13 B
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB 1.24 kB -11 B
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Rendered Page Sizes
vercel/next.js canary Janpot/next.js basePathz Change
index.html gzip 946 B 946 B
link.html gzip 952 B 952 B
withRouter.html gzip 939 B 939 B
Overall change 2.84 kB 2.84 kB

Diffs

Diff for _buildManifest.js
@@ -6,7 +6,7 @@ self.__BUILD_MANIFEST = {
   "/hooks": [
     "static\u002Fchunks\u002Fpages\u002Fhooks-8001dc76075832ee8949.js"
   ],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-a9269e283072f7ef2b5f.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-799bf459ab33248c435c.js"],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-2e9bfd441bd88cd3382e.js"
   ],
Diff for _buildManifest.module.js
@@ -9,7 +9,7 @@ self.__BUILD_MANIFEST = {
     "static\u002Fchunks\u002Fpages\u002Fhooks-56fa58a6f0993d7d36d7.module.js"
   ],
   "/link": [
-    "static\u002Fchunks\u002Fpages\u002Flink-9be23e1ed7374cb42e26.module.js"
+    "static\u002Fchunks\u002Fpages\u002Flink-47f633378b1969a46045.module.js"
   ],
   "/routerDirect": [
     "static\u002Fchunks\u002Fpages\u002FrouterDirect-368af3dfef3c9cd99dc3.module.js"
Diff for link-9be23e1..26.module.js
@@ -209,15 +209,10 @@
         var router = (0, _router.useRouter)();
         var pathname = (router && router.pathname) || "/";
 
-        var { href, as } = _react.default.useMemo(() => {
-          var resolvedHref = (0, _router2.resolveHref)(pathname, props.href);
-          return {
-            href: resolvedHref,
-            as: props.as
-              ? (0, _router2.resolveHref)(pathname, props.as)
-              : resolvedHref
-          };
-        }, [pathname, props.href, props.as]);
+        var { url: href, as } = _react.default.useMemo(
+          () => (0, _router2.prepareUrlAs)(pathname, props.href, props.as),
+          [pathname, props.href, props.as]
+        );
 
         _react.default.useEffect(() => {
           if (p && IntersectionObserver && childElm && childElm.tagName) {
Diff for link-a9269e2..2f7ef2b5f.js
@@ -220,20 +220,11 @@ _N_E = (window["webpackJsonp_N_E"] = window["webpackJsonp_N_E"] || []).push([
 
         var _react$default$useMem = _react["default"].useMemo(
             function() {
-              var resolvedHref = (0, _router2.resolveHref)(
-                pathname,
-                props.href
-              );
-              return {
-                href: resolvedHref,
-                as: props.as
-                  ? (0, _router2.resolveHref)(pathname, props.as)
-                  : resolvedHref
-              };
+              return (0, _router2.prepareUrlAs)(pathname, props.href, props.as);
             },
             [pathname, props.href, props.as]
           ),
-          href = _react$default$useMem.href,
+          href = _react$default$useMem.url,
           as = _react$default$useMem.as;
 
         _react["default"].useEffect(
Diff for 677f882d2ed8..a9.module.js
@@ -539,7 +539,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports.default = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -612,12 +612,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -724,10 +725,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
               return;
             }
@@ -754,11 +758,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -781,7 +787,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -808,10 +813,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
             }
 
@@ -883,7 +891,6 @@ 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(this, url, as));
           return this.change("pushState", url, as, options);
         }
         /**
@@ -902,11 +909,13 @@ 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(this, url, as));
           return this.change("replaceState", url, as, options);
         }
 
-        async change(method, url, as, options) {
+        async change(method, urlIn, asIn, options) {
+          var { url, as } = prepareUrlAs(this.pathname, urlIn, asIn);
+          var browserAs = addBasePath(as);
+
           if (!options._h) {
             this.isSsr = false;
           } // marking route changes as a navigation start entry
@@ -924,53 +933,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             this.abortComponentLoad(this._inFlightRoute);
           }
 
-          var cleanedAs = hasBasePath(as) ? delBasePath(as) : as;
-          this._inFlightRoute = as; // If the url change is only related to a hash change
+          this._inFlightRoute = browserAs; // If the url change is only related to a hash change
           // We should not proceed. We should only change the state.
           // WARNING: `_h` is an internal option for handing Next.js client-side
           // hydration. Your app should _never_ use this property. It may change at
           // any time without notice.
 
-          if (!options._h && this.onlyAHashChange(cleanedAs)) {
-            this.asPath = cleanedAs;
-            Router.events.emit("hashChangeStart", as);
+          if (!options._h && this.onlyAHashChange(as)) {
+            this.asPath = as;
+            Router.events.emit("hashChangeStart", browserAs);
             this.changeState(method, url, as, options);
-            this.scrollToHash(cleanedAs);
-            Router.events.emit("hashChangeComplete", as);
+            this.scrollToHash(as);
+            Router.events.emit("hashChangeComplete", browserAs);
             return true;
-          }
-
-          var parsed = tryParseRelativeUrl(url);
-          if (!parsed) return false;
-          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
-
-          pathname = pathname
-            ? (0, _normalizeTrailingSlash.removePathTrailingSlash)(
-                delBasePath(pathname)
-              )
-            : pathname; // If asked to change the current URL we should reload the current page
+          } // 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)
           // We should compare the new asPath to the current asPath, not the url
 
-          if (!this.urlIsNew(cleanedAs)) {
+          if (!this.urlIsNew(as)) {
             method = "replaceState";
           }
 
-          var route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          var parsed = tryParseRelativeUrl(url);
+          if (!parsed) return false;
+          var { pathname, searchParams } = parsed;
+          pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             pathname
           );
+          var route = pathname;
+          var query = (0, _searchParamsToUrlQuery.searchParamsToUrlQuery)(
+            searchParams
+          );
           var { shallow = false } = options;
 
           if ((0, _isDynamic.isDynamicRoute)(route)) {
             var { pathname: asPathname } = (0,
-            _parseRelativeUrl.parseRelativeUrl)(cleanedAs);
+            _parseRelativeUrl.parseRelativeUrl)(as);
             var routeRegex = (0, _routeRegex.getRouteRegex)(route);
             var routeMatch = (0, _routeMatcher.getRouteMatcher)(routeRegex)(
               asPathname
@@ -1001,35 +1001,35 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
           }
 
-          Router.events.emit("routeChangeStart", as);
+          Router.events.emit("routeChangeStart", browserAs);
 
           try {
             var routeInfo = await this.getRouteInfo(
               route,
               pathname,
               query,
-              as,
+              browserAs,
               shallow
             );
             var { error } = routeInfo;
-            Router.events.emit("beforeHistoryChange", as);
+            Router.events.emit("beforeHistoryChange", browserAs);
             this.changeState(method, url, as, options);
 
             if (false) {
               var appComp;
             }
 
-            await this.set(route, pathname, query, cleanedAs, routeInfo);
+            await this.set(route, pathname, query, as, routeInfo);
 
             if (error) {
-              Router.events.emit("routeChangeError", error, cleanedAs);
+              Router.events.emit("routeChangeError", error, browserAs);
               throw error;
             }
 
             if (false) {
             }
 
-            Router.events.emit("routeChangeComplete", as);
+            Router.events.emit("routeChangeComplete", browserAs);
             return true;
           } catch (err) {
             if (err.cancelled) {
@@ -1047,9 +1047,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               : {};
 
           if (false) {
-          }
+          } // _b is an internal option that indicates whether the basePath needs to be
+          // added. Defaults to true
 
-          if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+          var browserAs = options._b === false ? as : addBasePath(as);
+
+          if (method !== "pushState" || (0, _utils.getURL)() !== browserAs) {
             window.history[method](
               {
                 url,
@@ -1060,7 +1063,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               // Passing the empty string here should be safe against future changes to the method.
               // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
               "",
-              as
+              browserAs
             );
           }
         }
Diff for 677f882d2ed8..7f15aafe7.js
@@ -670,7 +670,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
       exports.hasBasePath = hasBasePath;
       exports.addBasePath = addBasePath;
       exports.delBasePath = delBasePath;
-      exports.resolveHref = resolveHref;
+      exports.prepareUrlAs = prepareUrlAs;
       exports["default"] = void 0;
 
       var _mitt = _interopRequireDefault(__webpack_require__("dZ6Y"));
@@ -743,12 +743,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
           : finalUrl.href;
       }
 
-      function prepareUrlAs(router, url, as) {
+      function prepareUrlAs(routerPath, url, as) {
         // If url and as provided as an object representation,
         // we'll format them into the string version here.
+        var href = resolveHref(routerPath, url);
         return {
-          url: addBasePath(resolveHref(router.pathname, url)),
-          as: as ? addBasePath(resolveHref(router.pathname, as)) : as
+          url: href,
+          as: as ? resolveHref(routerPath, as) : href
         };
       }
 
@@ -862,10 +863,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               _this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname2),
+                  pathname: _pathname2,
                   query: query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
 
               return;
@@ -897,11 +901,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
             }
 
             _this.change("replaceState", url, as, options);
-          }; // represents the current component key
+          };
 
-          this.route = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
+          this.pathname = (0, _normalizeTrailingSlash.removePathTrailingSlash)(
             _pathname
-          ); // set up the component cache (by route keys)
+          ); // represents the current component key
+
+          this.route = this.pathname; // set up the component cache (by route keys)
 
           this.components = {}; // We should not keep the cache, if there's an error
           // Otherwise, this cause issues when when going back and
@@ -924,7 +930,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
 
           this.events = Router.events;
           this.pageLoader = pageLoader;
-          this.pathname = _pathname;
           this.query = _query; // if auto prerendered and dynamic route wait to update asPath
           // until after mount to prevent hydration mismatch
 
@@ -951,10 +956,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
               this.changeState(
                 "replaceState",
                 (0, _utils.formatWithValidation)({
-                  pathname: addBasePath(_pathname),
+                  pathname: _pathname,
                   query: _query
                 }),
-                (0, _utils.getURL)()
+                (0, _utils.getURL)(),
+                {
+                  _b: false
+                }
               );
             }
 
@@ -1031,10 +1039,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs.url;
-                as = _prepareUrlAs.as;
                 return this.change("pushState", url, as, options);
               }
               /**
@@ -1055,10 +1059,6 @@ 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(this, url, as);
-
-                url = _prepareUrlAs2.url;
-                as = _prepareUrlAs2.as;
                 return this.change("replaceState", url, as, options);
               }
             },
@@ -1068,17 +1068,20 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                 var _change = _asyncToGenerator(
                   /*#__PURE__*/ _regeneratorRuntime.mark(function _callee(
                     method,
-                    url,
-                    as,
+                    urlIn,
+                    asIn,
                     options
                   ) {
-                    var rewriteUrlForNextExport,
-                      cleanedAs,
+                    var _prepareUrlAs,
+                      url,
+                      as,
+                      browserAs,
+                      rewriteUrlForNextExport,
                       parsed,
                       pathname,
                       searchParams,
-                      query,
                       route,
+                      query,
                       _options$shallow,
                       shallow,
                       _ref3,
@@ -1095,6 +1098,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                         while (1) {
                           switch ((_context.prev = _context.next)) {
                             case 0:
+                              (_prepareUrlAs = prepareUrlAs(
+                                this.pathname,
+                                urlIn,
+                                asIn
+                              )),
+                                (url = _prepareUrlAs.url),
+                                (as = _prepareUrlAs.as);
+                              browserAs = addBasePath(as);
+
                               if (!options._h) {
                                 this.isSsr = false;
                               } // marking route changes as a navigation start entry
@@ -1111,69 +1123,57 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                 this.abortComponentLoad(this._inFlightRoute);
                               }
 
-                              cleanedAs = hasBasePath(as)
-                                ? delBasePath(as)
-                                : as;
-                              this._inFlightRoute = as; // If the url change is only related to a hash change
+                              this._inFlightRoute = browserAs; // If the url change is only related to a hash change
                               // We should not proceed. We should only change the state.
                               // WARNING: `_h` is an internal option for handing Next.js client-side
                               // hydration. Your app should _never_ use this property. It may change at
                               // any time without notice.
 
-                              if (
-                                !(
-                                  !options._h && this.onlyAHashChange(cleanedAs)
-                                )
-                              ) {
-                                _context.next = 13;
+                              if (!(!options._h && this.onlyAHashChange(as))) {
+                                _context.next = 14;
                                 break;
                               }
 
-                              this.asPath = cleanedAs;
-                              Router.events.emit("hashChangeStart", as);
+                              this.asPath = as;
+                              Router.events.emit("hashChangeStart", browserAs);
                               this.changeState(method, url, as, options);
-                              this.scrollToHash(cleanedAs);
-                              Router.events.emit("hashChangeComplete", as);
+                              this.scrollToHash(as);
+                              Router.events.emit(
+                                "hashChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 13:
+                            case 14:
+                              // 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)
+                              // We should compare the new asPath to the current asPath, not the url
+                              if (!this.urlIsNew(as)) {
+                                method = "replaceState";
+                              }
+
                               parsed = tryParseRelativeUrl(url);
 
                               if (parsed) {
-                                _context.next = 16;
+                                _context.next = 18;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 16:
+                            case 18:
                               (pathname = parsed.pathname),
                                 (searchParams = parsed.searchParams);
+                              pathname = (0,
+                              _normalizeTrailingSlash.removePathTrailingSlash)(
+                                pathname
+                              );
+                              route = pathname;
                               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
-
-                              pathname = pathname
-                                ? (0,
-                                  _normalizeTrailingSlash.removePathTrailingSlash)(
-                                    delBasePath(pathname)
-                                  )
-                                : 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)
-                              // We should compare the new asPath to the current asPath, not the url
-
-                              if (!this.urlIsNew(cleanedAs)) {
-                                method = "replaceState";
-                              }
-
-                              route = (0,
-                              _normalizeTrailingSlash.removePathTrailingSlash)(
-                                pathname
                               );
                               (_options$shallow = options.shallow),
                                 (shallow =
@@ -1182,12 +1182,12 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                     : _options$shallow);
 
                               if (!(0, _isDynamic.isDynamicRoute)(route)) {
-                                _context.next = 34;
+                                _context.next = 35;
                                 break;
                               }
 
                               (_ref3 = (0, _parseRelativeUrl.parseRelativeUrl)(
-                                cleanedAs
+                                as
                               )),
                                 (asPathname = _ref3.pathname);
                               routeRegex = (0, _routeRegex.getRouteRegex)(
@@ -1198,7 +1198,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               )(asPathname);
 
                               if (routeMatch) {
-                                _context.next = 33;
+                                _context.next = 34;
                                 break;
                               }
 
@@ -1209,7 +1209,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                               });
 
                               if (!(missingParams.length > 0)) {
-                                _context.next = 31;
+                                _context.next = 32;
                                 break;
                               }
 
@@ -1226,79 +1226,85 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                                   "Read more: https://err.sh/vercel/next.js/incompatible-href-as"
                               );
 
-                            case 31:
-                              _context.next = 34;
+                            case 32:
+                              _context.next = 35;
                               break;
 
-                            case 33:
+                            case 34:
                               // Merge params into `query`, overwriting any specified in search
                               Object.assign(query, routeMatch);
 
-                            case 34:
-                              Router.events.emit("routeChangeStart", as);
-                              _context.prev = 35;
-                              _context.next = 38;
+                            case 35:
+                              Router.events.emit("routeChangeStart", browserAs);
+                              _context.prev = 36;
+                              _context.next = 39;
                               return this.getRouteInfo(
                                 route,
                                 pathname,
                                 query,
-                                as,
+                                browserAs,
                                 shallow
                               );
 
-                            case 38:
+                            case 39:
                               routeInfo = _context.sent;
                               error = routeInfo.error;
-                              Router.events.emit("beforeHistoryChange", as);
+                              Router.events.emit(
+                                "beforeHistoryChange",
+                                browserAs
+                              );
                               this.changeState(method, url, as, options);
 
                               if (false) {
                               }
 
-                              _context.next = 45;
+                              _context.next = 46;
                               return this.set(
                                 route,
                                 pathname,
                                 query,
-                                cleanedAs,
+                                as,
                                 routeInfo
                               );
 
-                            case 45:
+                            case 46:
                               if (!error) {
-                                _context.next = 48;
+                                _context.next = 49;
                                 break;
                               }
 
                               Router.events.emit(
                                 "routeChangeError",
                                 error,
-                                cleanedAs
+                                browserAs
                               );
                               throw error;
 
-                            case 48:
+                            case 49:
                               if (false) {
                               }
 
-                              Router.events.emit("routeChangeComplete", as);
+                              Router.events.emit(
+                                "routeChangeComplete",
+                                browserAs
+                              );
                               return _context.abrupt("return", true);
 
-                            case 53:
-                              _context.prev = 53;
-                              _context.t0 = _context["catch"](35);
+                            case 54:
+                              _context.prev = 54;
+                              _context.t0 = _context["catch"](36);
 
                               if (!_context.t0.cancelled) {
-                                _context.next = 57;
+                                _context.next = 58;
                                 break;
                               }
 
                               return _context.abrupt("return", false);
 
-                            case 57:
+                            case 58:
                               throw _context.t0;
 
-                            case 58:
+                            case 59:
                             case "end":
                               return _context.stop();
                           }
@@ -1306,7 +1312,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                       },
                       _callee,
                       this,
-                      [[35, 53]]
+                      [[36, 54]]
                     );
                   })
                 );
@@ -1327,9 +1333,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     : {};
 
                 if (false) {
-                }
+                } // _b is an internal option that indicates whether the basePath needs to be
+                // added. Defaults to true
+
+                var browserAs = options._b === false ? as : addBasePath(as);
 
-                if (method !== "pushState" || (0, _utils.getURL)() !== as) {
+                if (
+                  method !== "pushState" ||
+                  (0, _utils.getURL)() !== browserAs
+                ) {
                   window.history[method](
                     {
                       url: url,
@@ -1340,7 +1352,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
                     // Passing the empty string here should be safe against future changes to the method.
                     // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState
                     "",
-                    as
+                    browserAs
                   );
                 }
               }
Diff for index.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.535772574768133e6be7.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f620cea45847f15aafe7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.227ace7bbafd19d8df8a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.535772574768133e6be7.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for link.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.535772574768133e6be7.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -36,7 +36,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      href="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -122,13 +122,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f620cea45847f15aafe7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.227ace7bbafd19d8df8a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.535772574768133e6be7.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
@@ -146,13 +146,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-a9269e283072f7ef2b5f.js"
+      src="/_next/static/chunks/pages/link-799bf459ab33248c435c.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-9be23e1ed7374cb42e26.module.js"
+      src="/_next/static/chunks/pages/link-47f633378b1969a46045.module.js"
       async=""
       crossorigin="anonymous"
       type="module"
Diff for withRouter.html
@@ -24,7 +24,7 @@
     />
     <link
       rel="preload"
-      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      href="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.535772574768133e6be7.module.js"
       as="script"
       crossorigin="anonymous"
     />
@@ -117,13 +117,13 @@
       type="module"
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.f620cea45847f15aafe7.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.227ace7bbafd19d8df8a.js"
       async=""
       crossorigin="anonymous"
       nomodule=""
     ></script>
     <script
-      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.2ff1b0f9c6fe451560a9.module.js"
+      src="/_next/static/chunks/677f882d2ed86fa3467b8979053c1a4c3f8bc4df.535772574768133e6be7.module.js"
       async=""
       crossorigin="anonymous"
       type="module"

Serverless Mode (Increase detected ⚠️)
General Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
buildDuration 15.4s 15.8s ⚠️ +394ms
nodeModulesSize 65.5 MB 65.5 MB -756 B
Client Bundles (main, webpack, commons) Overall increase ⚠️
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..39a4.js gzip 10.2 kB N/A N/A
framework.HASH.js gzip 39.1 kB 39.1 kB
main-06588f2..f65e.js gzip 6.73 kB 6.73 kB
webpack-488d..c0e7.js gzip 751 B 751 B
677f882d2ed8..3901.js gzip N/A 10.2 kB N/A
Overall change 56.8 kB 56.8 kB ⚠️ +16 B
Client Bundles (main, webpack, commons) Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
677f882d2ed8..dule.js gzip 6.13 kB N/A N/A
framework.HA..dule.js gzip 39.1 kB 39.1 kB
main-62e1f09..dule.js gzip 5.81 kB 5.81 kB
webpack-4f62..dule.js gzip 751 B 751 B
677f882d2ed8..dule.js gzip N/A 6.12 kB N/A
Overall change 51.8 kB 51.8 kB -10 B
Legacy Client Bundles (polyfills)
vercel/next.js canary Janpot/next.js basePathz Change
polyfills-05..1236.js gzip 30.8 kB 30.8 kB
Overall change 30.8 kB 30.8 kB
Client Pages Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-8f5f611..1f7b.js gzip 1.28 kB 1.28 kB
_error-a98d9..5cb7.js gzip 3.45 kB 3.45 kB
hooks-f7f3d0..7465.js gzip 887 B 887 B
index-08fb3f..c0e9.js gzip 227 B 227 B
link-6f8445b..99e1.js gzip 1.3 kB N/A N/A
routerDirect..8aa1.js gzip 284 B 284 B
withRouter-f..e777.js gzip 284 B 284 B
link-e8656a0..f600.js gzip N/A 1.28 kB N/A
Overall change 7.72 kB 7.71 kB -13 B
Client Pages Modern Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_app-669dbe5..dule.js gzip 626 B 626 B
_error-d5979..dule.js gzip 2.3 kB 2.3 kB
hooks-805c40..dule.js gzip 387 B 387 B
index-6ba5a4..dule.js gzip 226 B 226 B
link-91516ae..dule.js gzip 1.25 kB N/A N/A
routerDirect..dule.js gzip 284 B 284 B
withRouter-d..dule.js gzip 282 B 282 B
link-f6acc53..dule.js gzip N/A 1.24 kB N/A
Overall change 5.36 kB 5.35 kB -11 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_buildManifest.js gzip 274 B 274 B
_buildManife..dule.js gzip 282 B 280 B -2 B
Overall change 556 B 554 B -2 B
Serverless bundles Overall decrease ✓
vercel/next.js canary Janpot/next.js basePathz Change
_error.js 1.02 MB 1.02 MB
404.html 4.18 kB 4.18 kB
hooks.html 3.82 kB 3.82 kB
index.js 1.02 MB 1.02 MB
link.js 1.06 MB 1.06 MB -307 B
routerDirect.js 1.05 MB 1.05 MB -163 B
withRouter.js 1.05 MB 1.05 MB -163 B
Overall change 5.2 MB 5.2 MB -633 B
Commit: 18136f5

@Janpot Janpot closed this Aug 6, 2020
LauraBeatris pushed a commit to LauraBeatris/next.js that referenced this pull request Sep 1, 2020
Caught this while reviewing router code for vercel#15710
@vercel vercel locked as resolved and limited conversation to collaborators Jan 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants