Skip to content

Commit

Permalink
Hoist the desired ReactDOM import expression (#36552)
Browse files Browse the repository at this point in the history
* hoist `react-dom/server` imports to reduce module load time in nodejs
* simplify `reactRoot` detection condition by checking the streaming rendering API we're using. (if it doesn't existed, like react 17, then we won't enable `reactRoot`)
* Merge `__NEXT_CONCURRENT_FEATURES` into `__NEXT_REACT_ROOT` env var since they're identical now
  • Loading branch information
huozhi committed Apr 28, 2022
1 parent 2444569 commit cd7419e
Show file tree
Hide file tree
Showing 9 changed files with 23 additions and 38 deletions.
7 changes: 7 additions & 0 deletions packages/next/bin/next.ts
Expand Up @@ -42,6 +42,10 @@ const args = arg(
}
)

// Detect if react-dom is enabled streaming rendering mode
const shouldUseReactRoot = !!require('react-dom/server.browser')
.renderToReadableStream

// Version is inlined into the file using taskr build pipeline
if (args['--version']) {
console.log(`Next.js v${process.env.__NEXT_VERSION}`)
Expand Down Expand Up @@ -105,6 +109,9 @@ if (process.env.NODE_ENV) {

;(process.env as any).NODE_ENV = process.env.NODE_ENV || defaultEnv
;(process.env as any).NEXT_RUNTIME = 'nodejs'
if (shouldUseReactRoot) {
;(process.env as any).__NEXT_REACT_ROOT = 'true'
}

// x-ref: https://github.com/vercel/next.js/pull/34688#issuecomment-1047994505
if (process.versions.pnp === '3') {
Expand Down
5 changes: 2 additions & 3 deletions packages/next/build/index.ts
@@ -1,3 +1,4 @@
import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack'
import { loadEnvConfig } from '@next/env'
import chalk from 'next/dist/compiled/chalk'
import crypto from 'crypto'
Expand Down Expand Up @@ -109,9 +110,7 @@ import { NextConfigComplete } from '../server/config-shared'
import isError, { NextError } from '../lib/is-error'
import { TelemetryPlugin } from './webpack/plugins/telemetry-plugin'
import { MiddlewareManifest } from './webpack/plugins/middleware-plugin'
import type { webpack5 as webpack } from 'next/dist/compiled/webpack/webpack'
import { recursiveCopy } from '../lib/recursive-copy'
import { shouldUseReactRoot } from '../server/config'
import { recursiveReadDir } from '../lib/recursive-readdir'
import { lockfilePatchPromise } from './swc'

Expand Down Expand Up @@ -164,7 +163,7 @@ export default async function build(

// We enable concurrent features (Fizz-related rendering architecture) when
// using React 18 or experimental.
const hasReactRoot = shouldUseReactRoot()
const hasReactRoot = !!process.env.__NEXT_REACT_ROOT
const hasConcurrentFeatures = hasReactRoot
const hasServerComponents =
hasReactRoot && !!config.experimental.serverComponents
Expand Down
3 changes: 0 additions & 3 deletions packages/next/build/webpack-config.ts
Expand Up @@ -1399,9 +1399,6 @@ export default async function getBaseWebpackConfig(
config.reactStrictMode
),
'process.env.__NEXT_REACT_ROOT': JSON.stringify(hasReactRoot),
'process.env.__NEXT_CONCURRENT_FEATURES': JSON.stringify(
hasConcurrentFeatures
),
'process.env.__NEXT_RSC': JSON.stringify(hasServerComponents),
'process.env.__NEXT_OPTIMIZE_FONTS': JSON.stringify(
config.optimizeFonts && !dev
Expand Down
16 changes: 1 addition & 15 deletions packages/next/server/config.ts
Expand Up @@ -2,7 +2,6 @@ import { basename, extname, relative, isAbsolute, resolve } from 'path'
import { pathToFileURL } from 'url'
import { Agent as HttpAgent } from 'http'
import { Agent as HttpsAgent } from 'https'
import semver from 'next/dist/compiled/semver'
import findUp from 'next/dist/compiled/find-up'
import chalk from '../lib/chalk'
import * as Log from '../build/output/log'
Expand Down Expand Up @@ -188,7 +187,7 @@ function assignDefaults(userConfig: { [key: string]: any }) {
}
}

const hasReactRoot = shouldUseReactRoot()
const hasReactRoot = process.env.__NEXT_REACT_ROOT
if (hasReactRoot) {
// users might not have the `experimental` key in their config
result.experimental = result.experimental || {}
Expand Down Expand Up @@ -753,19 +752,6 @@ export default async function loadConfig(
return completeConfig
}

export const shouldUseReactRoot = execOnce(() => {
const reactDomVersion = require('react-dom').version
const isReactExperimental = Boolean(
reactDomVersion && /0\.0\.0-experimental/.test(reactDomVersion)
)
const hasReact18: boolean =
Boolean(reactDomVersion) &&
(semver.gte(reactDomVersion!, '18.0.0') ||
semver.coerce(reactDomVersion)?.version === '18.0.0')

return hasReact18 || isReactExperimental
})

export function setHttpAgentOptions(
options: NextConfigComplete['httpAgentOptions']
) {
Expand Down
3 changes: 1 addition & 2 deletions packages/next/server/dev/hot-reloader.ts
Expand Up @@ -38,7 +38,6 @@ import { getProperError } from '../../lib/is-error'
import ws from 'next/dist/compiled/ws'
import { promises as fs } from 'fs'
import { getPageRuntime } from '../../build/entries'
import { shouldUseReactRoot } from '../config'

const wsServer = new ws.Server({ noServer: true })

Expand Down Expand Up @@ -199,7 +198,7 @@ export default class HotReloader {

this.config = config
this.runtime = config.experimental.runtime
this.hasReactRoot = shouldUseReactRoot()
this.hasReactRoot = !!process.env.__NEXT_REACT_ROOT
this.hasServerComponents =
this.hasReactRoot && !!config.experimental.serverComponents
this.previewProps = previewProps
Expand Down
6 changes: 3 additions & 3 deletions packages/next/server/node-web-streams-helper.ts
Expand Up @@ -132,18 +132,18 @@ export function createFlushEffectStream(
})
}

export async function renderToInitialStream({
export function renderToInitialStream({
ReactDOMServer,
element,
}: {
ReactDOMServer: typeof import('react-dom/server')
ReactDOMServer: any
element: React.ReactElement
}): Promise<
ReadableStream<Uint8Array> & {
allReady?: Promise<void>
}
> {
return await (ReactDOMServer as any).renderToReadableStream(element)
return ReactDOMServer.renderToReadableStream(element)
}

export async function continueFromInitialStream({
Expand Down
17 changes: 7 additions & 10 deletions packages/next/server/render.tsx
Expand Up @@ -88,6 +88,9 @@ let warn: typeof import('../build/output/log').warn
let postProcess: typeof import('../shared/lib/post-process').default

const DOCTYPE = '<!DOCTYPE html>'
const ReactDOMServer = process.env.__NEXT_REACT_ROOT
? require('react-dom/server.browser')
: require('react-dom/server')

if (process.env.NEXT_RUNTIME !== 'edge') {
require('./node-polyfill-web-streams')
Expand Down Expand Up @@ -486,20 +489,17 @@ export async function renderToHTML(
devOnlyCacheBusterQueryString,
supportsDynamicHTML,
images,
reactRoot,
runtime: globalRuntime,
ComponentMod,
AppMod,
AppServerMod,
} = renderOpts

const hasConcurrentFeatures = reactRoot

let Document = renderOpts.Document

// We don't need to opt-into the flight inlining logic if the page isn't a RSC.
const isServerComponent =
hasConcurrentFeatures &&
!!process.env.__NEXT_REACT_ROOT &&
!!serverComponentManifest &&
!!ComponentMod.__next_rsc__?.server

Expand Down Expand Up @@ -1292,10 +1292,6 @@ export async function renderToHTML(
return inAmpMode ? children : <div id="__next">{children}</div>
}

const ReactDOMServer = hasConcurrentFeatures
? require('react-dom/server.browser')
: require('react-dom/server')

/**
* Rules of Static & Dynamic HTML:
*
Expand Down Expand Up @@ -1436,7 +1432,7 @@ export async function renderToHTML(
)
}

if (!hasConcurrentFeatures) {
if (!process.env.__NEXT_REACT_ROOT) {
if (Document.getInitialProps) {
const documentInitialPropsRes = await documentInitialProps()
if (documentInitialPropsRes === null) return null
Expand Down Expand Up @@ -1543,7 +1539,8 @@ export async function renderToHTML(
renderStream,
suffix,
dataStream: serverComponentsInlinedTransformStream?.readable,
generateStaticHTML: generateStaticHTML || !hasConcurrentFeatures,
generateStaticHTML:
generateStaticHTML || !process.env.__NEXT_REACT_ROOT,
flushEffectHandler,
})
}
Expand Down
2 changes: 1 addition & 1 deletion packages/next/shared/lib/dynamic.tsx
Expand Up @@ -118,7 +118,7 @@ export default function dynamic<P = {}>(
loader: Loader<P>
}
// Error if Fizz rendering is not enabled and `suspense` option is set to true
if (!process.env.__NEXT_CONCURRENT_FEATURES && suspenseOptions.suspense) {
if (!process.env.__NEXT_REACT_ROOT && suspenseOptions.suspense) {
throw new Error(
`Invalid suspense option usage in next/dynamic. Read more: https://nextjs.org/docs/messages/invalid-dynamic-suspense`
)
Expand Down
2 changes: 1 addition & 1 deletion packages/next/shared/lib/head.tsx
Expand Up @@ -164,7 +164,7 @@ function reduceComponents(
}
if (
process.env.NODE_ENV === 'development' &&
process.env.__NEXT_CONCURRENT_FEATURES
process.env.__NEXT_REACT_ROOT
) {
// omit JSON-LD structured data snippets from the warning
if (c.type === 'script' && c.props['type'] !== 'application/ld+json') {
Expand Down

1 comment on commit cd7419e

@ijjk
Copy link
Member

@ijjk ijjk commented on cd7419e Apr 28, 2022

Choose a reason for hiding this comment

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

Stats from current release

Default Build (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
buildDuration 14.7s 14.8s ⚠️ +126ms
buildDurationCached 6.2s 6.2s ⚠️ +35ms
nodeModulesSize 82.7 MB 83.3 MB ⚠️ +522 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
/ failed reqs 0 0
/ total time (seconds) 3.243 3.675 ⚠️ +0.43
/ avg req/sec 770.98 680.36 ⚠️ -90.62
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.375 1.369 -0.01
/error-in-render avg req/sec 1818 1826.49 +8.49
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
925.HASH.js gzip 179 B 179 B
framework-HASH.js gzip 42 kB 42 kB
main-HASH.js gzip 28.3 kB 28.6 kB ⚠️ +318 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 72 kB 72.3 kB ⚠️ +318 B
Legacy Client Bundles (polyfills)
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
_app-HASH.js gzip 1.36 kB 1.36 kB ⚠️ +1 B
_error-HASH.js gzip 192 B 193 B ⚠️ +1 B
amp-HASH.js gzip 309 B 308 B -1 B
css-HASH.js gzip 327 B 327 B
dynamic-HASH.js gzip 3.05 kB 3.08 kB ⚠️ +30 B
head-HASH.js gzip 351 B 359 B ⚠️ +8 B
hooks-HASH.js gzip 920 B 920 B
image-HASH.js gzip 5.73 kB 5.71 kB -17 B
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.36 kB 2.64 kB ⚠️ +280 B
routerDirect..HASH.js gzip 320 B 320 B
script-HASH.js gzip 392 B 391 B -1 B
withRouter-HASH.js gzip 319 B 318 B -1 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 16 kB 16.3 kB ⚠️ +300 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
_buildManifest.js gzip 460 B 459 B -1 B
Overall change 460 B 459 B -1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
index.html gzip 530 B 531 B ⚠️ +1 B
link.html gzip 544 B 544 B
withRouter.html gzip 525 B 526 B ⚠️ +1 B
Overall change 1.6 kB 1.6 kB ⚠️ +2 B

Diffs

Diff for _buildManifest.js
@@ -1,25 +1,25 @@
 self.__BUILD_MANIFEST = {
   __rewrites: { beforeFiles: [], afterFiles: [], fallback: [] },
-  "/": ["static\u002Fchunks\u002Fpages\u002Findex-a49797fad5e5a39b.js"],
-  "/_error": ["static\u002Fchunks\u002Fpages\u002F_error-5d03de5a43fe90da.js"],
-  "/amp": ["static\u002Fchunks\u002Fpages\u002Famp-3eb62f36e98a75e2.js"],
+  "/": ["static\u002Fchunks\u002Fpages\u002Findex-7eff8c9e187d9f9d.js"],
+  "/_error": ["static\u002Fchunks\u002Fpages\u002F_error-f87d4319387a4b59.js"],
+  "/amp": ["static\u002Fchunks\u002Fpages\u002Famp-56b55622017aff70.js"],
   "/css": [
     "static\u002Fcss\u002F94fdbc56eafa2039.css",
-    "static\u002Fchunks\u002Fpages\u002Fcss-f8d6ff68a6e8b080.js"
+    "static\u002Fchunks\u002Fpages\u002Fcss-436fa6bb26fc4120.js"
   ],
   "/dynamic": [
-    "static\u002Fchunks\u002Fpages\u002Fdynamic-f3793288d6fe105a.js"
+    "static\u002Fchunks\u002Fpages\u002Fdynamic-80f5580e1c1b8ce3.js"
   ],
-  "/head": ["static\u002Fchunks\u002Fpages\u002Fhead-96a5d6ed07cf5a83.js"],
-  "/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-9dfe734f583d4926.js"],
-  "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-5597cb692d5dcc6b.js"],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-c605640c895e01ab.js"],
+  "/head": ["static\u002Fchunks\u002Fpages\u002Fhead-544bb68363445a0e.js"],
+  "/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-c1372eeb4916d32c.js"],
+  "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-75136b1767faacf3.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-ca5e63d57db66cd2.js"],
   "/routerDirect": [
-    "static\u002Fchunks\u002Fpages\u002FrouterDirect-98eb70bf22fb21da.js"
+    "static\u002Fchunks\u002Fpages\u002FrouterDirect-113a7082ae16fbcb.js"
   ],
-  "/script": ["static\u002Fchunks\u002Fpages\u002Fscript-1d699e963b4c9346.js"],
+  "/script": ["static\u002Fchunks\u002Fpages\u002Fscript-3ef13c748c65083c.js"],
   "/withRouter": [
-    "static\u002Fchunks\u002Fpages\u002FwithRouter-ee616b01250df021.js"
+    "static\u002Fchunks\u002Fpages\u002FwithRouter-04f6802cebd3d340.js"
   ],
   sortedPages: [
     "\u002F",
Diff for _app-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [888],
   {
-    /***/ 915: /***/ function(
+    /***/ 1597: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -282,7 +282,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 179], function() {
-      return __webpack_exec__(915), __webpack_exec__(880);
+      return __webpack_exec__(1597), __webpack_exec__(880);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for _error-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [820],
   {
-    /***/ 4977: /***/ function(
+    /***/ 1981: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -24,7 +24,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [888, 774, 179], function() {
-      return __webpack_exec__(4977);
+      return __webpack_exec__(1981);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for amp-HASH.js
@@ -11,7 +11,7 @@
       /***/
     },
 
-    /***/ 6071: /***/ function(
+    /***/ 6005: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -47,6 +47,9 @@
       /* harmony import */ var next_amp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
         9135
       );
+      /* harmony import */ var next_amp__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(
+        next_amp__WEBPACK_IMPORTED_MODULE_0__
+      );
 
       var config = {
         amp: "hybrid"
@@ -66,7 +69,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [888, 774, 179], function() {
-      return __webpack_exec__(6071);
+      return __webpack_exec__(6005);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for css-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [706],
   {
-    /***/ 7083: /***/ function(
+    /***/ 6518: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -61,7 +61,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(7083);
+      return __webpack_exec__(6518);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for dynamic-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [739],
   {
-    /***/ 1893: /***/ function(
+    /***/ 4665: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -18,13 +18,8 @@
       /***/
     },
 
-    /***/ 7645: /***/ function(
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) {
+    /***/ 7645: /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var __webpack_unused_export__;
 
       function _defineProperty(obj, key, value) {
         if (key in obj) {
@@ -67,11 +62,11 @@
         }
         return target;
       }
-      __webpack_unused_export__ = {
+      Object.defineProperty(exports, "__esModule", {
         value: true
-      };
+      });
       exports["default"] = dynamic;
-      __webpack_unused_export__ = noSSR;
+      exports.noSSR = noSSR;
       var _react = _interopRequireDefault(__webpack_require__(7294));
       var _loadable = _interopRequireDefault(__webpack_require__(4588));
       function dynamic(dynamicOptions, options) {
@@ -160,6 +155,13 @@
             timedOut: false
           });
         };
+      }
+      if (
+        typeof exports.default === "function" ||
+        (typeof exports.default === "object" && exports.default !== null)
+      ) {
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
       } //# sourceMappingURL=dynamic.js.map
 
       /***/
@@ -586,9 +588,11 @@
       /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
         5152
       );
+      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(
+        next_dynamic__WEBPACK_IMPORTED_MODULE_1__
+      );
 
-      var DynamicHello = (0,
-      next_dynamic__WEBPACK_IMPORTED_MODULE_1__["default"])(
+      var DynamicHello = next_dynamic__WEBPACK_IMPORTED_MODULE_1___default()(
         function() {
           return __webpack_require__
             .e(/* import() */ 925)
@@ -633,10 +637,10 @@
       __webpack_require__
     ) {
       var __dirname = "/";
-      (() => {
+      (function() {
         "use strict";
         var e = {
-          800: e => {
+          800: function(e) {
             /*
 object-assign
 (c) Sindre Sorhus
@@ -713,7 +717,7 @@ object-assign
                   return i;
                 };
           },
-          569: (e, r, t) => {
+          569: function(e, r, t) {
             /** @license React vundefined
              * use-subscription.development.js
              *
@@ -725,7 +729,7 @@ object-assign
             if (false) {
             }
           },
-          403: (e, r, t) => {
+          403: function(e, r, t) {
             /** @license React vundefined
              * use-subscription.production.min.js
              *
@@ -775,13 +779,13 @@ object-assign
               return a;
             };
           },
-          138: (e, r, t) => {
+          138: function(e, r, t) {
             if (true) {
               e.exports = t(403);
             } else {
             }
           },
-          522: e => {
+          522: function(e) {
             e.exports = __webpack_require__(7294);
           }
         };
@@ -826,7 +830,7 @@ object-assign
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(1893);
+      return __webpack_exec__(4665);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for head-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [645],
   {
-    /***/ 4251: /***/ function(
+    /***/ 528: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -37,6 +37,9 @@
       /* harmony import */ var next_head__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
         9008
       );
+      /* harmony import */ var next_head__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(
+        next_head__WEBPACK_IMPORTED_MODULE_1__
+      );
 
       var Page = function() {
         return /*#__PURE__*/ (0,
@@ -46,7 +49,7 @@
             children: [
               /*#__PURE__*/ (0,
               react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
-                next_head__WEBPACK_IMPORTED_MODULE_1__["default"],
+                next_head__WEBPACK_IMPORTED_MODULE_1___default(),
                 {
                   children: /*#__PURE__*/ (0,
                   react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("title", {
@@ -84,7 +87,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(4251);
+      return __webpack_exec__(528);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for hooks-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [757],
   {
-    /***/ 1470: /***/ function(
+    /***/ 8459: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -158,7 +158,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(1470);
+      return __webpack_exec__(8459);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for image-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [358],
   {
-    /***/ 2361: /***/ function(
+    /***/ 8700: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -149,7 +149,6 @@
           objectFit = _param.objectFit,
           objectPosition = _param.objectPosition,
           onLoadingComplete = _param.onLoadingComplete,
-          onError = _param.onError,
           _placeholder = _param.placeholder,
           placeholder = _placeholder === void 0 ? "empty" : _placeholder,
           blurDataURL = _param.blurDataURL,
@@ -169,7 +168,6 @@
             "objectFit",
             "objectPosition",
             "onLoadingComplete",
-            "onError",
             "placeholder",
             "blurDataURL"
           ]);
@@ -327,11 +325,7 @@
         var imgStyle = Object.assign(
           {},
           style,
-          layout === "raw"
-            ? {
-                aspectRatio: "".concat(widthInt, " / ").concat(heightInt)
-              }
-            : layoutStyle
+          layout === "raw" ? {} : layoutStyle
         );
         var blurStyle =
           placeholder === "blur" && !blurComplete
@@ -870,7 +864,7 @@
             });
           }
           if (false) {
-            var parent, ref3;
+            var parent, widthModified, heightModified, ref3;
           }
         });
       }
@@ -893,6 +887,7 @@
           onLoadingCompleteRef = _param.onLoadingCompleteRef,
           setBlurComplete = _param.setBlurComplete,
           setIntersection = _param.setIntersection,
+          onLoad = _param.onLoad,
           onError = _param.onError,
           isVisible = _param.isVisible,
           rest = _objectWithoutProperties(_param, [
@@ -914,6 +909,7 @@
             "onLoadingCompleteRef",
             "setBlurComplete",
             "setIntersection",
+            "onLoad",
             "onError",
             "isVisible"
           ]);
@@ -926,7 +922,7 @@
               {},
               rest,
               imgAttributes,
-              layout === "raw" && !imgAttributes.sizes
+              layout === "raw"
                 ? {
                     height: heightInt,
                     width: widthInt
@@ -972,6 +968,9 @@
                     onLoadingCompleteRef,
                     setBlurComplete
                   );
+                  if (onLoad) {
+                    onLoad(event);
+                  }
                 },
                 onError: function(event) {
                   if (placeholder === "blur") {
@@ -1004,7 +1003,7 @@
                     sizes: imgAttributes.sizes,
                     loader: loader
                   }),
-                  layout === "raw" && !imgAttributes.sizes
+                  layout === "raw"
                     ? {
                         height: heightInt,
                         width: widthInt
@@ -1388,7 +1387,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(2361);
+      return __webpack_exec__(8700);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for index-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [405],
   {
-    /***/ 8581: /***/ function(
+    /***/ 5557: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -46,7 +46,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [888, 774, 179], function() {
-      return __webpack_exec__(8581);
+      return __webpack_exec__(5557);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for link-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [644],
   {
-    /***/ 7847: /***/ function(
+    /***/ 8129: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -105,6 +105,34 @@
               default: obj
             };
       }
+      function _objectWithoutProperties(source, excluded) {
+        if (source == null) return {};
+        var target = _objectWithoutPropertiesLoose(source, excluded);
+        var key, i;
+        if (Object.getOwnPropertySymbols) {
+          var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
+          for (i = 0; i < sourceSymbolKeys.length; i++) {
+            key = sourceSymbolKeys[i];
+            if (excluded.indexOf(key) >= 0) continue;
+            if (!Object.prototype.propertyIsEnumerable.call(source, key))
+              continue;
+            target[key] = source[key];
+          }
+        }
+        return target;
+      }
+      function _objectWithoutPropertiesLoose(source, excluded) {
+        if (source == null) return {};
+        var target = {};
+        var sourceKeys = Object.keys(source);
+        var key, i;
+        for (i = 0; i < sourceKeys.length; i++) {
+          key = sourceKeys[i];
+          if (excluded.indexOf(key) >= 0) continue;
+          target[key] = source[key];
+        }
+        return target;
+      }
       var prefetched = {};
       function prefetch(router, href, as, options) {
         if (false || !router) return;
@@ -163,7 +191,15 @@
           scroll: scroll
         });
       }
-      function Link(props) {
+      var Link = /*#__PURE__*/ _react.default.forwardRef(function(
+        props,
+        forwardedRef
+      ) {
+        var _legacyBehavior = props.legacyBehavior,
+          legacyBehavior =
+            _legacyBehavior === void 0
+              ? Boolean(false) !== true
+              : _legacyBehavior;
         if (false) {
           var hasWarned,
             optionalProps,
@@ -172,48 +208,73 @@
             requiredPropsGuard,
             createPropError;
         }
-        var p = props.prefetch !== false;
+        var children;
+        var hrefProp = props.href,
+          asProp = props.as,
+          childrenProp = props.children,
+          prefetchProp = props.prefetch,
+          passHref = props.passHref,
+          replace = props.replace,
+          shallow = props.shallow,
+          scroll = props.scroll,
+          locale = props.locale,
+          onClick = props.onClick,
+          onMouseEnter = props.onMouseEnter,
+          restProps = _objectWithoutProperties(props, [
+            "href",
+            "as",
+            "children",
+            "prefetch",
+            "passHref",
+            "replace",
+            "shallow",
+            "scroll",
+            "locale",
+            "onClick",
+            "onMouseEnter"
+          ]);
+        children = childrenProp;
+        if (legacyBehavior && typeof children === "string") {
+          children = /*#__PURE__*/ _react.default.createElement(
+            "a",
+            null,
+            children
+          );
+        }
+        var p = prefetchProp !== false;
         var router = (0, _router1).useRouter();
         var ref2 = _react.default.useMemo(
             function() {
               var ref = _slicedToArray(
-                  (0, _router).resolveHref(router, props.href, true),
+                  (0, _router).resolveHref(router, hrefProp, true),
                   2
                 ),
                 resolvedHref = ref[0],
                 resolvedAs = ref[1];
               return {
                 href: resolvedHref,
-                as: props.as
-                  ? (0, _router).resolveHref(router, props.as)
+                as: asProp
+                  ? (0, _router).resolveHref(router, asProp)
                   : resolvedAs || resolvedHref
               };
             },
-            [router, props.href, props.as]
+            [router, hrefProp, asProp]
           ),
           href = ref2.href,
           as = ref2.as;
         var previousHref = _react.default.useRef(href);
         var previousAs = _react.default.useRef(as);
-        var children = props.children,
-          replace = props.replace,
-          shallow = props.shallow,
-          scroll = props.scroll,
-          locale = props.locale;
-        if (typeof children === "string") {
-          children = /*#__PURE__*/ _react.default.createElement(
-            "a",
-            null,
-            children
-          );
-        }
         // This will return the first child, if multiple are provided it will throw an error
         var child;
-        if (false) {
-        } else {
-          child = _react.default.Children.only(children);
+        if (legacyBehavior) {
+          if (false) {
+          } else {
+            child = _react.default.Children.only(children);
+          }
         }
-        var childRef = child && typeof child === "object" && child.ref;
+        var childRef = legacyBehavior
+          ? child && typeof child === "object" && child.ref
+          : forwardedRef;
         var ref1 = _slicedToArray(
             (0, _useIntersection).useIntersection({
               rootMargin: "200px"
@@ -262,7 +323,14 @@
           onClick: function(e) {
             if (false) {
             }
-            if (child.props && typeof child.props.onClick === "function") {
+            if (!legacyBehavior && typeof onClick === "function") {
+              onClick(e);
+            }
+            if (
+              legacyBehavior &&
+              child.props &&
+              typeof child.props.onClick === "function"
+            ) {
               child.props.onClick(e);
             }
             if (!e.defaultPrevented) {
@@ -277,22 +345,30 @@
                 locale
               );
             }
-          }
-        };
-        childProps.onMouseEnter = function(e) {
-          if (child.props && typeof child.props.onMouseEnter === "function") {
-            child.props.onMouseEnter(e);
-          }
-          if ((0, _router).isLocalURL(href)) {
-            prefetch(router, href, as, {
-              priority: true
-            });
+          },
+          onMouseEnter: function(e) {
+            if (!legacyBehavior && typeof onMouseEnter === "function") {
+              onMouseEnter(e);
+            }
+            if (
+              legacyBehavior &&
+              child.props &&
+              typeof child.props.onMouseEnter === "function"
+            ) {
+              child.props.onMouseEnter(e);
+            }
+            if ((0, _router).isLocalURL(href)) {
+              prefetch(router, href, as, {
+                priority: true
+              });
+            }
           }
         };
         // If child is an <a> tag and doesn't have a href attribute, or if the 'passHref' property is
         // defined, we specify the current 'href', so that repetition is not needed by the user
         if (
-          props.passHref ||
+          !legacyBehavior ||
+          passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
           var curLocale1 =
@@ -318,8 +394,14 @@
               )
             );
         }
-        return /*#__PURE__*/ _react.default.cloneElement(child, childProps);
-      }
+        return legacyBehavior
+          ? /*#__PURE__*/ _react.default.cloneElement(child, childProps)
+          : /*#__PURE__*/ _react.default.createElement(
+              "a",
+              Object.assign({}, restProps, childProps),
+              children
+            );
+      });
       var _default = Link;
       exports["default"] = _default;
       if (
@@ -608,7 +690,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(7847);
+      return __webpack_exec__(8129);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for routerDirect-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [58],
   {
-    /***/ 5448: /***/ function(
+    /***/ 4525: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -73,7 +73,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(5448);
+      return __webpack_exec__(4525);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for script-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [797],
   {
-    /***/ 5344: /***/ function(
+    /***/ 846: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -86,7 +86,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(5344);
+      return __webpack_exec__(846);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for withRouter-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [807],
   {
-    /***/ 6744: /***/ function(
+    /***/ 9704: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -70,7 +70,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(6744);
+      return __webpack_exec__(9704);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for main-HASH.js
@@ -627,7 +627,7 @@
         }
         return target;
       }
-      var version = "12.1.5";
+      var version = "12.1.6-canary.14";
       exports.version = version;
       var router;
       exports.router = router;
@@ -2875,6 +2875,16 @@
       function _arrayWithHoles(arr) {
         if (Array.isArray(arr)) return arr;
       }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
       function _iterableToArrayLimit(arr, i) {
         var _i =
           arr == null
@@ -2908,6 +2918,11 @@
           "Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
         );
       }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
       function _slicedToArray(arr, i) {
         return (
           _arrayWithHoles(arr) ||
@@ -2916,6 +2931,14 @@
           _nonIterableRest()
         );
       }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
       function _unsupportedIterableToArray(o, minLen) {
         if (!o) return;
         if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -2931,6 +2954,7 @@
       Object.defineProperty(exports, "__esModule", {
         value: true
       });
+      exports.handleClientScriptLoad = handleClientScriptLoad;
       exports.initScriptLoader = initScriptLoader;
       exports["default"] = void 0;
       var _react = _interopRequireWildcard(__webpack_require__(7294));
@@ -3129,14 +3153,14 @@
       function handleClientScriptLoad(props) {
         var _strategy = props.strategy,
           strategy = _strategy === void 0 ? "afterInteractive" : _strategy;
-        if (strategy === "afterInteractive") {
-          loadScript(props);
-        } else if (strategy === "lazyOnload") {
+        if (strategy === "lazyOnload") {
           window.addEventListener("load", function() {
             (0, _requestIdleCallback).requestIdleCallback(function() {
               return loadScript(props);
             });
           });
+        } else {
+          loadScript(props);
         }
       }
       function loadLazyScript(props) {
@@ -3152,8 +3176,22 @@
           });
         }
       }
+      function addBeforeInteractiveToCache() {
+        var scripts = _toConsumableArray(
+          document.querySelectorAll('[data-nscript="beforeInteractive"]')
+        ).concat(
+          _toConsumableArray(
+            document.querySelectorAll('[data-nscript="beforePageRender"]')
+          )
+        );
+        scripts.forEach(function(script) {
+          var cacheKey = script.id || script.getAttribute("src");
+          LoadCache.add(cacheKey);
+        });
+      }
       function initScriptLoader(scriptLoaderItems) {
         scriptLoaderItems.forEach(handleClientScriptLoad);
+        addBeforeInteractiveToCache();
       }
       function Script(props) {
         var _src = props.src,
@@ -3516,30 +3554,31 @@
                 {
                   style: styles.error
                 },
-                true &&
+                /*#__PURE__*/ _react.default.createElement(
+                  _head.default,
+                  null,
                   /*#__PURE__*/ _react.default.createElement(
-                    _head.default,
+                    "title",
                     null,
-                    /*#__PURE__*/ _react.default.createElement(
-                      "title",
-                      null,
-                      statusCode
-                        ? "".concat(statusCode, ": ").concat(title)
-                        : "Application error: a client-side exception has occurred"
-                    )
-                  ),
+                    statusCode
+                      ? "".concat(statusCode, ": ").concat(title)
+                      : "Application error: a client-side exception has occurred"
+                  )
+                ),
                 /*#__PURE__*/ _react.default.createElement(
                   "div",
                   null,
                   /*#__PURE__*/ _react.default.createElement("style", {
                     dangerouslySetInnerHTML: {
-                      __html: "body { margin: 0 }"
+                      __html:
+                        "\n                body { margin: 0; color: #000; background: #fff; }\n                .next-error-h1 {\n                  border-right: 1px solid rgba(0, 0, 0, .3);\n                }\n                @media (prefers-color-scheme: dark) {\n                  body { color: #fff; background: #000; }\n                  .next-error-h1 {\n                    border-right: 1px solid rgba(255, 255, 255, .3);\n                  }\n                }"
                     }
                   }),
                   statusCode
                     ? /*#__PURE__*/ _react.default.createElement(
                         "h1",
                         {
+                          className: "next-error-h1",
                           style: styles.h1
                         },
                         statusCode
@@ -3578,8 +3617,6 @@
       Error.origGetInitialProps = _getInitialProps;
       var styles = {
         error: {
-          color: "#000",
-          background: "#fff",
           fontFamily:
             '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
           height: "100vh",
@@ -3598,7 +3635,6 @@
         },
         h1: {
           display: "inline-block",
-          borderRight: "1px solid rgba(0, 0, 0,.3)",
           margin: 0,
           marginRight: "20px",
           padding: "10px 23px 10px 0",
@@ -3645,11 +3681,7 @@
       /***/
     },
 
-    /***/ 1686: /***/ function(
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) {
+    /***/ 1686: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -3682,6 +3714,13 @@
         return isInAmpMode(
           _react.default.useContext(_ampContext.AmpStateContext)
         );
+      }
+      if (
+        typeof exports.default === "function" ||
+        (typeof exports.default === "object" && exports.default !== null)
+      ) {
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
       } //# sourceMappingURL=amp.js.map
 
       /***/
@@ -3694,8 +3733,15 @@
         value: true
       });
       exports.escapeStringRegexp = escapeStringRegexp;
+      // regexp is based on https://github.com/sindresorhus/escape-string-regexp
+      var reHasRegExp = /[|\\{}()[\]^$+*?.-]/;
+      var reReplaceRegExp = /[|\\{}()[\]^$+*?.-]/g;
       function escapeStringRegexp(str) {
-        return str.replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&");
+        // see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23
+        if (reHasRegExp.test(str)) {
+          return str.replace(reReplaceRegExp, "\\$&");
+        }
+        return str;
       } //# sourceMappingURL=escape-regexp.js.map
 
       /***/
@@ -3728,11 +3774,7 @@
       /***/
     },
 
-    /***/ 3121: /***/ function(
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) {
+    /***/ 3121: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
       function _defineProperty(obj, key, value) {
@@ -3977,7 +4019,14 @@
         );
       }
       var _default = Head;
-      exports["default"] = _default; //# sourceMappingURL=head.js.map
+      exports["default"] = _default;
+      if (
+        typeof exports.default === "function" ||
+        (typeof exports.default === "object" && exports.default !== null)
+      ) {
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
+      } //# sourceMappingURL=head.js.map
 
       /***/
     },
@@ -4397,6 +4446,7 @@
       exports["default"] = void 0;
       var _normalizeTrailingSlash = __webpack_require__(2700);
       var _routeLoader = __webpack_require__(2497);
+      var _script = __webpack_require__(3573);
       var _isError = _interopRequireWildcard(__webpack_require__(676));
       var _denormalizePagePath = __webpack_require__(4522);
       var _normalizeLocalePath = __webpack_require__(4769);
@@ -5066,6 +5116,8 @@
                     props,
                     __N_SSG,
                     __N_SSP,
+                    component,
+                    scripts,
                     destination,
                     parsedHref,
                     ref3,
@@ -5559,14 +5611,25 @@
                               (props = routeInfo.props),
                               (__N_SSG = routeInfo.__N_SSG),
                               (__N_SSP = routeInfo.__N_SSP);
+                            component = routeInfo.Component;
+                            if (component && component.unstable_scriptLoader) {
+                              scripts = [].concat(
+                                component.unstable_scriptLoader()
+                              );
+                              scripts.forEach(function(script) {
+                                (0, _script).handleClientScriptLoad(
+                                  script.props
+                                );
+                              });
+                            }
                             if (!((__N_SSG || __N_SSP) && props)) {
-                              _ctx.next = 144;
+                              _ctx.next = 146;
                               break;
                             }
                             if (
                               !(props.pageProps && props.pageProps.__N_REDIRECT)
                             ) {
-                              _ctx.next = 129;
+                              _ctx.next = 131;
                               break;
                             }
                             destination = props.pageProps.__N_REDIRECT;
@@ -5576,7 +5639,7 @@
                                 props.pageProps.__N_REDIRECT_BASE_PATH !== false
                               )
                             ) {
-                              _ctx.next = 127;
+                              _ctx.next = 129;
                               break;
                             }
                             parsedHref = (0,
@@ -5596,31 +5659,31 @@
                               "return",
                               _this.change(method, newUrl, newAs, options)
                             );
-                          case 127:
+                          case 129:
                             window.location.href = destination;
                             return _ctx.abrupt(
                               "return",
                               new Promise(function() {})
                             );
-                          case 129:
+                          case 131:
                             nextState.isPreview = !!props.__N_PREVIEW;
                             if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
-                              _ctx.next = 144;
+                              _ctx.next = 146;
                               break;
                             }
-                            _ctx.prev = 132;
-                            _ctx.next = 135;
+                            _ctx.prev = 134;
+                            _ctx.next = 137;
                             return _this.fetchComponent("/404");
-                          case 135:
+                          case 137:
                             notFoundRoute = "/404";
-                            _ctx.next = 141;
+                            _ctx.next = 143;
                             break;
-                          case 138:
-                            _ctx.prev = 138;
-                            _ctx.t3 = _ctx["catch"](132);
+                          case 140:
+                            _ctx.prev = 140;
+                            _ctx.t3 = _ctx["catch"](134);
                             notFoundRoute = "/_error";
-                          case 141:
-                            _ctx.next = 143;
+                          case 143:
+                            _ctx.next = 145;
                             return _this.getRouteInfo(
                               notFoundRoute,
                               notFoundRoute,
@@ -5633,9 +5696,9 @@
                               nextState.locale,
                               nextState.isPreview
                             );
-                          case 143:
+                          case 145:
                             routeInfo = _ctx.sent;
-                          case 144:
+                          case 146:
                             Router.events.emit(
                               "beforeHistoryChange",
                               as,
@@ -5673,7 +5736,7 @@
                                   y: 0
                                 }
                               : null;
-                            _ctx.next = 153;
+                            _ctx.next = 155;
                             return _this
                               .set(
                                 _objectSpread({}, nextState, {
@@ -5692,9 +5755,9 @@
                                 if (e.cancelled) error = error || e;
                                 else throw e;
                               });
-                          case 153:
+                          case 155:
                             if (!error) {
-                              _ctx.next = 156;
+                              _ctx.next = 158;
                               break;
                             }
                             Router.events.emit(
@@ -5704,7 +5767,7 @@
                               routeProps
                             );
                             throw error;
-                          case 156:
+                          case 158:
                             if (false) {
                             }
                             Router.events.emit(
@@ -5713,8 +5776,8 @@
                               routeProps
                             );
                             return _ctx.abrupt("return", true);
-                          case 161:
-                            _ctx.prev = 161;
+                          case 163:
+                            _ctx.prev = 163;
                             _ctx.t4 = _ctx["catch"](113);
                             if (
                               !(
@@ -5722,13 +5785,13 @@
                                 _ctx.t4.cancelled
                               )
                             ) {
-                              _ctx.next = 165;
+                              _ctx.next = 167;
                               break;
                             }
                             return _ctx.abrupt("return", false);
-                          case 165:
+                          case 167:
                             throw _ctx.t4;
-                          case 166:
+                          case 168:
                           case "end":
                             return _ctx.stop();
                         }
@@ -5737,8 +5800,8 @@
                     null,
                     [
                       [39, 51],
-                      [113, 161],
-                      [132, 138]
+                      [113, 163],
+                      [134, 140]
                     ]
                   );
                 })
Diff for index.html
@@ -19,15 +19,15 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-6c28bc120ef33497.js"
+      src="/_next/static/chunks/main-ac58a1e29dd8158c.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-cf4319dec8fb8d46.js"
+      src="/_next/static/chunks/pages/_app-bfaa0e36469b32e4.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/index-a49797fad5e5a39b.js"
+      src="/_next/static/chunks/pages/index-7eff8c9e187d9f9d.js"
       defer=""
     ></script>
     <script src="/_next/static/BUILD_ID/_buildManifest.js" defer=""></script>
Diff for link.html
@@ -19,15 +19,15 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-6c28bc120ef33497.js"
+      src="/_next/static/chunks/main-ac58a1e29dd8158c.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-cf4319dec8fb8d46.js"
+      src="/_next/static/chunks/pages/_app-bfaa0e36469b32e4.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-c605640c895e01ab.js"
+      src="/_next/static/chunks/pages/link-ca5e63d57db66cd2.js"
       defer=""
     ></script>
     <script src="/_next/static/BUILD_ID/_buildManifest.js" defer=""></script>
Diff for withRouter.html
@@ -19,15 +19,15 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-6c28bc120ef33497.js"
+      src="/_next/static/chunks/main-ac58a1e29dd8158c.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-cf4319dec8fb8d46.js"
+      src="/_next/static/chunks/pages/_app-bfaa0e36469b32e4.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/withRouter-ee616b01250df021.js"
+      src="/_next/static/chunks/pages/withRouter-04f6802cebd3d340.js"
       defer=""
     ></script>
     <script src="/_next/static/BUILD_ID/_buildManifest.js" defer=""></script>

Default Build with SWC (Increase detected ⚠️)
General Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
buildDuration 12s 11.9s -28ms
buildDurationCached 6.2s 6.2s ⚠️ +54ms
nodeModulesSize 82.7 MB 83.3 MB ⚠️ +522 kB
Page Load Tests Overall decrease ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
/ failed reqs 0 0
/ total time (seconds) 3.204 3.665 ⚠️ +0.46
/ avg req/sec 780.16 682.07 ⚠️ -98.09
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.359 1.348 -0.01
/error-in-render avg req/sec 1839.27 1855.06 +15.79
Client Bundles (main, webpack) Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
925.HASH.js gzip 178 B 178 B
framework-HASH.js gzip 42.2 kB 42.2 kB
main-HASH.js gzip 28.7 kB 29.1 kB ⚠️ +357 B
webpack-HASH.js gzip 1.45 kB 1.45 kB
Overall change 72.6 kB 72.9 kB ⚠️ +357 B
Legacy Client Bundles (polyfills)
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
polyfills-HASH.js gzip 31 kB 31 kB
Overall change 31 kB 31 kB
Client Pages Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
_app-HASH.js gzip 1.35 kB 1.35 kB ⚠️ +1 B
_error-HASH.js gzip 179 B 179 B
amp-HASH.js gzip 313 B 312 B -1 B
css-HASH.js gzip 325 B 324 B -1 B
dynamic-HASH.js gzip 3.03 kB 3.08 kB ⚠️ +56 B
head-HASH.js gzip 351 B 357 B ⚠️ +6 B
hooks-HASH.js gzip 921 B 921 B
image-HASH.js gzip 5.78 kB 5.76 kB -14 B
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.44 kB 2.76 kB ⚠️ +328 B
routerDirect..HASH.js gzip 322 B 322 B
script-HASH.js gzip 393 B 392 B -1 B
withRouter-HASH.js gzip 317 B 317 B
85e02e95b279..7e3.css gzip 107 B 107 B
Overall change 16.1 kB 16.5 kB ⚠️ +374 B
Client Build Manifests Overall decrease ✓
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
_buildManifest.js gzip 459 B 458 B -1 B
Overall change 459 B 458 B -1 B
Rendered Page Sizes Overall increase ⚠️
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
index.html gzip 529 B 529 B
link.html gzip 542 B 543 B ⚠️ +1 B
withRouter.html gzip 524 B 526 B ⚠️ +2 B
Overall change 1.59 kB 1.6 kB ⚠️ +3 B

Diffs

Diff for _buildManifest.js
@@ -1,25 +1,25 @@
 self.__BUILD_MANIFEST = {
   __rewrites: { beforeFiles: [], afterFiles: [], fallback: [] },
-  "/": ["static\u002Fchunks\u002Fpages\u002Findex-a49797fad5e5a39b.js"],
-  "/_error": ["static\u002Fchunks\u002Fpages\u002F_error-5d03de5a43fe90da.js"],
-  "/amp": ["static\u002Fchunks\u002Fpages\u002Famp-3eb62f36e98a75e2.js"],
+  "/": ["static\u002Fchunks\u002Fpages\u002Findex-7eff8c9e187d9f9d.js"],
+  "/_error": ["static\u002Fchunks\u002Fpages\u002F_error-f87d4319387a4b59.js"],
+  "/amp": ["static\u002Fchunks\u002Fpages\u002Famp-56b55622017aff70.js"],
   "/css": [
     "static\u002Fcss\u002F94fdbc56eafa2039.css",
-    "static\u002Fchunks\u002Fpages\u002Fcss-f8d6ff68a6e8b080.js"
+    "static\u002Fchunks\u002Fpages\u002Fcss-436fa6bb26fc4120.js"
   ],
   "/dynamic": [
-    "static\u002Fchunks\u002Fpages\u002Fdynamic-f3793288d6fe105a.js"
+    "static\u002Fchunks\u002Fpages\u002Fdynamic-80f5580e1c1b8ce3.js"
   ],
-  "/head": ["static\u002Fchunks\u002Fpages\u002Fhead-96a5d6ed07cf5a83.js"],
-  "/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-9dfe734f583d4926.js"],
-  "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-5597cb692d5dcc6b.js"],
-  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-c605640c895e01ab.js"],
+  "/head": ["static\u002Fchunks\u002Fpages\u002Fhead-544bb68363445a0e.js"],
+  "/hooks": ["static\u002Fchunks\u002Fpages\u002Fhooks-c1372eeb4916d32c.js"],
+  "/image": ["static\u002Fchunks\u002Fpages\u002Fimage-75136b1767faacf3.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-ca5e63d57db66cd2.js"],
   "/routerDirect": [
-    "static\u002Fchunks\u002Fpages\u002FrouterDirect-98eb70bf22fb21da.js"
+    "static\u002Fchunks\u002Fpages\u002FrouterDirect-113a7082ae16fbcb.js"
   ],
-  "/script": ["static\u002Fchunks\u002Fpages\u002Fscript-1d699e963b4c9346.js"],
+  "/script": ["static\u002Fchunks\u002Fpages\u002Fscript-3ef13c748c65083c.js"],
   "/withRouter": [
-    "static\u002Fchunks\u002Fpages\u002FwithRouter-ee616b01250df021.js"
+    "static\u002Fchunks\u002Fpages\u002FwithRouter-04f6802cebd3d340.js"
   ],
   sortedPages: [
     "\u002F",
Diff for _app-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [888],
   {
-    /***/ 915: /***/ function(
+    /***/ 1597: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -282,7 +282,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 179], function() {
-      return __webpack_exec__(915), __webpack_exec__(880);
+      return __webpack_exec__(1597), __webpack_exec__(880);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for _error-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [820],
   {
-    /***/ 4977: /***/ function(
+    /***/ 1981: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -24,7 +24,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [888, 774, 179], function() {
-      return __webpack_exec__(4977);
+      return __webpack_exec__(1981);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for amp-HASH.js
@@ -11,7 +11,7 @@
       /***/
     },
 
-    /***/ 6071: /***/ function(
+    /***/ 6005: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -47,6 +47,9 @@
       /* harmony import */ var next_amp__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
         9135
       );
+      /* harmony import */ var next_amp__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(
+        next_amp__WEBPACK_IMPORTED_MODULE_0__
+      );
 
       var config = {
         amp: "hybrid"
@@ -66,7 +69,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [888, 774, 179], function() {
-      return __webpack_exec__(6071);
+      return __webpack_exec__(6005);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for css-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [706],
   {
-    /***/ 7083: /***/ function(
+    /***/ 6518: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -61,7 +61,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(7083);
+      return __webpack_exec__(6518);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for dynamic-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [739],
   {
-    /***/ 1893: /***/ function(
+    /***/ 4665: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -18,13 +18,8 @@
       /***/
     },
 
-    /***/ 7645: /***/ function(
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) {
+    /***/ 7645: /***/ function(module, exports, __webpack_require__) {
       "use strict";
-      var __webpack_unused_export__;
 
       function _defineProperty(obj, key, value) {
         if (key in obj) {
@@ -67,11 +62,11 @@
         }
         return target;
       }
-      __webpack_unused_export__ = {
+      Object.defineProperty(exports, "__esModule", {
         value: true
-      };
+      });
       exports["default"] = dynamic;
-      __webpack_unused_export__ = noSSR;
+      exports.noSSR = noSSR;
       var _react = _interopRequireDefault(__webpack_require__(7294));
       var _loadable = _interopRequireDefault(__webpack_require__(4588));
       function dynamic(dynamicOptions, options) {
@@ -160,6 +155,13 @@
             timedOut: false
           });
         };
+      }
+      if (
+        typeof exports.default === "function" ||
+        (typeof exports.default === "object" && exports.default !== null)
+      ) {
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
       } //# sourceMappingURL=dynamic.js.map
 
       /***/
@@ -586,9 +588,11 @@
       /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
         5152
       );
+      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(
+        next_dynamic__WEBPACK_IMPORTED_MODULE_1__
+      );
 
-      var DynamicHello = (0,
-      next_dynamic__WEBPACK_IMPORTED_MODULE_1__["default"])(
+      var DynamicHello = next_dynamic__WEBPACK_IMPORTED_MODULE_1___default()(
         function() {
           return __webpack_require__
             .e(/* import() */ 925)
@@ -633,10 +637,10 @@
       __webpack_require__
     ) {
       var __dirname = "/";
-      (() => {
+      (function() {
         "use strict";
         var e = {
-          800: e => {
+          800: function(e) {
             /*
 object-assign
 (c) Sindre Sorhus
@@ -713,7 +717,7 @@ object-assign
                   return i;
                 };
           },
-          569: (e, r, t) => {
+          569: function(e, r, t) {
             /** @license React vundefined
              * use-subscription.development.js
              *
@@ -725,7 +729,7 @@ object-assign
             if (false) {
             }
           },
-          403: (e, r, t) => {
+          403: function(e, r, t) {
             /** @license React vundefined
              * use-subscription.production.min.js
              *
@@ -775,13 +779,13 @@ object-assign
               return a;
             };
           },
-          138: (e, r, t) => {
+          138: function(e, r, t) {
             if (true) {
               e.exports = t(403);
             } else {
             }
           },
-          522: e => {
+          522: function(e) {
             e.exports = __webpack_require__(7294);
           }
         };
@@ -826,7 +830,7 @@ object-assign
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(1893);
+      return __webpack_exec__(4665);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for head-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [645],
   {
-    /***/ 4251: /***/ function(
+    /***/ 528: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -37,6 +37,9 @@
       /* harmony import */ var next_head__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(
         9008
       );
+      /* harmony import */ var next_head__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(
+        next_head__WEBPACK_IMPORTED_MODULE_1__
+      );
 
       var Page = function() {
         return /*#__PURE__*/ (0,
@@ -46,7 +49,7 @@
             children: [
               /*#__PURE__*/ (0,
               react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
-                next_head__WEBPACK_IMPORTED_MODULE_1__["default"],
+                next_head__WEBPACK_IMPORTED_MODULE_1___default(),
                 {
                   children: /*#__PURE__*/ (0,
                   react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("title", {
@@ -84,7 +87,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(4251);
+      return __webpack_exec__(528);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for hooks-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [757],
   {
-    /***/ 1470: /***/ function(
+    /***/ 8459: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -158,7 +158,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(1470);
+      return __webpack_exec__(8459);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for image-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [358],
   {
-    /***/ 2361: /***/ function(
+    /***/ 8700: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -149,7 +149,6 @@
           objectFit = _param.objectFit,
           objectPosition = _param.objectPosition,
           onLoadingComplete = _param.onLoadingComplete,
-          onError = _param.onError,
           _placeholder = _param.placeholder,
           placeholder = _placeholder === void 0 ? "empty" : _placeholder,
           blurDataURL = _param.blurDataURL,
@@ -169,7 +168,6 @@
             "objectFit",
             "objectPosition",
             "onLoadingComplete",
-            "onError",
             "placeholder",
             "blurDataURL"
           ]);
@@ -327,11 +325,7 @@
         var imgStyle = Object.assign(
           {},
           style,
-          layout === "raw"
-            ? {
-                aspectRatio: "".concat(widthInt, " / ").concat(heightInt)
-              }
-            : layoutStyle
+          layout === "raw" ? {} : layoutStyle
         );
         var blurStyle =
           placeholder === "blur" && !blurComplete
@@ -870,7 +864,7 @@
             });
           }
           if (false) {
-            var parent, ref3;
+            var parent, widthModified, heightModified, ref3;
           }
         });
       }
@@ -893,6 +887,7 @@
           onLoadingCompleteRef = _param.onLoadingCompleteRef,
           setBlurComplete = _param.setBlurComplete,
           setIntersection = _param.setIntersection,
+          onLoad = _param.onLoad,
           onError = _param.onError,
           isVisible = _param.isVisible,
           rest = _objectWithoutProperties(_param, [
@@ -914,6 +909,7 @@
             "onLoadingCompleteRef",
             "setBlurComplete",
             "setIntersection",
+            "onLoad",
             "onError",
             "isVisible"
           ]);
@@ -926,7 +922,7 @@
               {},
               rest,
               imgAttributes,
-              layout === "raw" && !imgAttributes.sizes
+              layout === "raw"
                 ? {
                     height: heightInt,
                     width: widthInt
@@ -972,6 +968,9 @@
                     onLoadingCompleteRef,
                     setBlurComplete
                   );
+                  if (onLoad) {
+                    onLoad(event);
+                  }
                 },
                 onError: function(event) {
                   if (placeholder === "blur") {
@@ -1004,7 +1003,7 @@
                     sizes: imgAttributes.sizes,
                     loader: loader
                   }),
-                  layout === "raw" && !imgAttributes.sizes
+                  layout === "raw"
                     ? {
                         height: heightInt,
                         width: widthInt
@@ -1388,7 +1387,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(2361);
+      return __webpack_exec__(8700);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for index-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [405],
   {
-    /***/ 8581: /***/ function(
+    /***/ 5557: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -46,7 +46,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [888, 774, 179], function() {
-      return __webpack_exec__(8581);
+      return __webpack_exec__(5557);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for link-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [644],
   {
-    /***/ 7847: /***/ function(
+    /***/ 8129: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -105,6 +105,34 @@
               default: obj
             };
       }
+      function _objectWithoutProperties(source, excluded) {
+        if (source == null) return {};
+        var target = _objectWithoutPropertiesLoose(source, excluded);
+        var key, i;
+        if (Object.getOwnPropertySymbols) {
+          var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
+          for (i = 0; i < sourceSymbolKeys.length; i++) {
+            key = sourceSymbolKeys[i];
+            if (excluded.indexOf(key) >= 0) continue;
+            if (!Object.prototype.propertyIsEnumerable.call(source, key))
+              continue;
+            target[key] = source[key];
+          }
+        }
+        return target;
+      }
+      function _objectWithoutPropertiesLoose(source, excluded) {
+        if (source == null) return {};
+        var target = {};
+        var sourceKeys = Object.keys(source);
+        var key, i;
+        for (i = 0; i < sourceKeys.length; i++) {
+          key = sourceKeys[i];
+          if (excluded.indexOf(key) >= 0) continue;
+          target[key] = source[key];
+        }
+        return target;
+      }
       var prefetched = {};
       function prefetch(router, href, as, options) {
         if (false || !router) return;
@@ -163,7 +191,15 @@
           scroll: scroll
         });
       }
-      function Link(props) {
+      var Link = /*#__PURE__*/ _react.default.forwardRef(function(
+        props,
+        forwardedRef
+      ) {
+        var _legacyBehavior = props.legacyBehavior,
+          legacyBehavior =
+            _legacyBehavior === void 0
+              ? Boolean(false) !== true
+              : _legacyBehavior;
         if (false) {
           var hasWarned,
             optionalProps,
@@ -172,48 +208,73 @@
             requiredPropsGuard,
             createPropError;
         }
-        var p = props.prefetch !== false;
+        var children;
+        var hrefProp = props.href,
+          asProp = props.as,
+          childrenProp = props.children,
+          prefetchProp = props.prefetch,
+          passHref = props.passHref,
+          replace = props.replace,
+          shallow = props.shallow,
+          scroll = props.scroll,
+          locale = props.locale,
+          onClick = props.onClick,
+          onMouseEnter = props.onMouseEnter,
+          restProps = _objectWithoutProperties(props, [
+            "href",
+            "as",
+            "children",
+            "prefetch",
+            "passHref",
+            "replace",
+            "shallow",
+            "scroll",
+            "locale",
+            "onClick",
+            "onMouseEnter"
+          ]);
+        children = childrenProp;
+        if (legacyBehavior && typeof children === "string") {
+          children = /*#__PURE__*/ _react.default.createElement(
+            "a",
+            null,
+            children
+          );
+        }
+        var p = prefetchProp !== false;
         var router = (0, _router1).useRouter();
         var ref2 = _react.default.useMemo(
             function() {
               var ref = _slicedToArray(
-                  (0, _router).resolveHref(router, props.href, true),
+                  (0, _router).resolveHref(router, hrefProp, true),
                   2
                 ),
                 resolvedHref = ref[0],
                 resolvedAs = ref[1];
               return {
                 href: resolvedHref,
-                as: props.as
-                  ? (0, _router).resolveHref(router, props.as)
+                as: asProp
+                  ? (0, _router).resolveHref(router, asProp)
                   : resolvedAs || resolvedHref
               };
             },
-            [router, props.href, props.as]
+            [router, hrefProp, asProp]
           ),
           href = ref2.href,
           as = ref2.as;
         var previousHref = _react.default.useRef(href);
         var previousAs = _react.default.useRef(as);
-        var children = props.children,
-          replace = props.replace,
-          shallow = props.shallow,
-          scroll = props.scroll,
-          locale = props.locale;
-        if (typeof children === "string") {
-          children = /*#__PURE__*/ _react.default.createElement(
-            "a",
-            null,
-            children
-          );
-        }
         // This will return the first child, if multiple are provided it will throw an error
         var child;
-        if (false) {
-        } else {
-          child = _react.default.Children.only(children);
+        if (legacyBehavior) {
+          if (false) {
+          } else {
+            child = _react.default.Children.only(children);
+          }
         }
-        var childRef = child && typeof child === "object" && child.ref;
+        var childRef = legacyBehavior
+          ? child && typeof child === "object" && child.ref
+          : forwardedRef;
         var ref1 = _slicedToArray(
             (0, _useIntersection).useIntersection({
               rootMargin: "200px"
@@ -262,7 +323,14 @@
           onClick: function(e) {
             if (false) {
             }
-            if (child.props && typeof child.props.onClick === "function") {
+            if (!legacyBehavior && typeof onClick === "function") {
+              onClick(e);
+            }
+            if (
+              legacyBehavior &&
+              child.props &&
+              typeof child.props.onClick === "function"
+            ) {
               child.props.onClick(e);
             }
             if (!e.defaultPrevented) {
@@ -277,22 +345,30 @@
                 locale
               );
             }
-          }
-        };
-        childProps.onMouseEnter = function(e) {
-          if (child.props && typeof child.props.onMouseEnter === "function") {
-            child.props.onMouseEnter(e);
-          }
-          if ((0, _router).isLocalURL(href)) {
-            prefetch(router, href, as, {
-              priority: true
-            });
+          },
+          onMouseEnter: function(e) {
+            if (!legacyBehavior && typeof onMouseEnter === "function") {
+              onMouseEnter(e);
+            }
+            if (
+              legacyBehavior &&
+              child.props &&
+              typeof child.props.onMouseEnter === "function"
+            ) {
+              child.props.onMouseEnter(e);
+            }
+            if ((0, _router).isLocalURL(href)) {
+              prefetch(router, href, as, {
+                priority: true
+              });
+            }
           }
         };
         // If child is an <a> tag and doesn't have a href attribute, or if the 'passHref' property is
         // defined, we specify the current 'href', so that repetition is not needed by the user
         if (
-          props.passHref ||
+          !legacyBehavior ||
+          passHref ||
           (child.type === "a" && !("href" in child.props))
         ) {
           var curLocale1 =
@@ -318,8 +394,14 @@
               )
             );
         }
-        return /*#__PURE__*/ _react.default.cloneElement(child, childProps);
-      }
+        return legacyBehavior
+          ? /*#__PURE__*/ _react.default.cloneElement(child, childProps)
+          : /*#__PURE__*/ _react.default.createElement(
+              "a",
+              Object.assign({}, restProps, childProps),
+              children
+            );
+      });
       var _default = Link;
       exports["default"] = _default;
       if (
@@ -608,7 +690,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(7847);
+      return __webpack_exec__(8129);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for routerDirect-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [58],
   {
-    /***/ 5448: /***/ function(
+    /***/ 4525: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -73,7 +73,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(5448);
+      return __webpack_exec__(4525);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for script-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [797],
   {
-    /***/ 5344: /***/ function(
+    /***/ 846: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -86,7 +86,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(5344);
+      return __webpack_exec__(846);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for withRouter-HASH.js
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [807],
   {
-    /***/ 6744: /***/ function(
+    /***/ 9704: /***/ function(
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -70,7 +70,7 @@
       return __webpack_require__((__webpack_require__.s = moduleId));
     };
     /******/ __webpack_require__.O(0, [774, 888, 179], function() {
-      return __webpack_exec__(6744);
+      return __webpack_exec__(9704);
     });
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
Diff for main-HASH.js
@@ -627,7 +627,7 @@
         }
         return target;
       }
-      var version = "12.1.5";
+      var version = "12.1.6-canary.14";
       exports.version = version;
       var router;
       exports.router = router;
@@ -2875,6 +2875,16 @@
       function _arrayWithHoles(arr) {
         if (Array.isArray(arr)) return arr;
       }
+      function _arrayWithoutHoles(arr) {
+        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
+      }
+      function _iterableToArray(iter) {
+        if (
+          (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null) ||
+          iter["@@iterator"] != null
+        )
+          return Array.from(iter);
+      }
       function _iterableToArrayLimit(arr, i) {
         var _i =
           arr == null
@@ -2908,6 +2918,11 @@
           "Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
         );
       }
+      function _nonIterableSpread() {
+        throw new TypeError(
+          "Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."
+        );
+      }
       function _slicedToArray(arr, i) {
         return (
           _arrayWithHoles(arr) ||
@@ -2916,6 +2931,14 @@
           _nonIterableRest()
         );
       }
+      function _toConsumableArray(arr) {
+        return (
+          _arrayWithoutHoles(arr) ||
+          _iterableToArray(arr) ||
+          _unsupportedIterableToArray(arr) ||
+          _nonIterableSpread()
+        );
+      }
       function _unsupportedIterableToArray(o, minLen) {
         if (!o) return;
         if (typeof o === "string") return _arrayLikeToArray(o, minLen);
@@ -2931,6 +2954,7 @@
       Object.defineProperty(exports, "__esModule", {
         value: true
       });
+      exports.handleClientScriptLoad = handleClientScriptLoad;
       exports.initScriptLoader = initScriptLoader;
       exports["default"] = void 0;
       var _react = _interopRequireWildcard(__webpack_require__(7294));
@@ -3129,14 +3153,14 @@
       function handleClientScriptLoad(props) {
         var _strategy = props.strategy,
           strategy = _strategy === void 0 ? "afterInteractive" : _strategy;
-        if (strategy === "afterInteractive") {
-          loadScript(props);
-        } else if (strategy === "lazyOnload") {
+        if (strategy === "lazyOnload") {
           window.addEventListener("load", function() {
             (0, _requestIdleCallback).requestIdleCallback(function() {
               return loadScript(props);
             });
           });
+        } else {
+          loadScript(props);
         }
       }
       function loadLazyScript(props) {
@@ -3152,8 +3176,22 @@
           });
         }
       }
+      function addBeforeInteractiveToCache() {
+        var scripts = _toConsumableArray(
+          document.querySelectorAll('[data-nscript="beforeInteractive"]')
+        ).concat(
+          _toConsumableArray(
+            document.querySelectorAll('[data-nscript="beforePageRender"]')
+          )
+        );
+        scripts.forEach(function(script) {
+          var cacheKey = script.id || script.getAttribute("src");
+          LoadCache.add(cacheKey);
+        });
+      }
       function initScriptLoader(scriptLoaderItems) {
         scriptLoaderItems.forEach(handleClientScriptLoad);
+        addBeforeInteractiveToCache();
       }
       function Script(props) {
         var _src = props.src,
@@ -3516,30 +3554,31 @@
                 {
                   style: styles.error
                 },
-                true &&
+                /*#__PURE__*/ _react.default.createElement(
+                  _head.default,
+                  null,
                   /*#__PURE__*/ _react.default.createElement(
-                    _head.default,
+                    "title",
                     null,
-                    /*#__PURE__*/ _react.default.createElement(
-                      "title",
-                      null,
-                      statusCode
-                        ? "".concat(statusCode, ": ").concat(title)
-                        : "Application error: a client-side exception has occurred"
-                    )
-                  ),
+                    statusCode
+                      ? "".concat(statusCode, ": ").concat(title)
+                      : "Application error: a client-side exception has occurred"
+                  )
+                ),
                 /*#__PURE__*/ _react.default.createElement(
                   "div",
                   null,
                   /*#__PURE__*/ _react.default.createElement("style", {
                     dangerouslySetInnerHTML: {
-                      __html: "body { margin: 0 }"
+                      __html:
+                        "\n                body { margin: 0; color: #000; background: #fff; }\n                .next-error-h1 {\n                  border-right: 1px solid rgba(0, 0, 0, .3);\n                }\n                @media (prefers-color-scheme: dark) {\n                  body { color: #fff; background: #000; }\n                  .next-error-h1 {\n                    border-right: 1px solid rgba(255, 255, 255, .3);\n                  }\n                }"
                     }
                   }),
                   statusCode
                     ? /*#__PURE__*/ _react.default.createElement(
                         "h1",
                         {
+                          className: "next-error-h1",
                           style: styles.h1
                         },
                         statusCode
@@ -3578,8 +3617,6 @@
       Error.origGetInitialProps = _getInitialProps;
       var styles = {
         error: {
-          color: "#000",
-          background: "#fff",
           fontFamily:
             '-apple-system, BlinkMacSystemFont, Roboto, "Segoe UI", "Fira Sans", Avenir, "Helvetica Neue", "Lucida Grande", sans-serif',
           height: "100vh",
@@ -3598,7 +3635,6 @@
         },
         h1: {
           display: "inline-block",
-          borderRight: "1px solid rgba(0, 0, 0,.3)",
           margin: 0,
           marginRight: "20px",
           padding: "10px 23px 10px 0",
@@ -3645,11 +3681,7 @@
       /***/
     },
 
-    /***/ 1686: /***/ function(
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) {
+    /***/ 1686: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -3682,6 +3714,13 @@
         return isInAmpMode(
           _react.default.useContext(_ampContext.AmpStateContext)
         );
+      }
+      if (
+        typeof exports.default === "function" ||
+        (typeof exports.default === "object" && exports.default !== null)
+      ) {
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
       } //# sourceMappingURL=amp.js.map
 
       /***/
@@ -3694,8 +3733,15 @@
         value: true
       });
       exports.escapeStringRegexp = escapeStringRegexp;
+      // regexp is based on https://github.com/sindresorhus/escape-string-regexp
+      var reHasRegExp = /[|\\{}()[\]^$+*?.-]/;
+      var reReplaceRegExp = /[|\\{}()[\]^$+*?.-]/g;
       function escapeStringRegexp(str) {
-        return str.replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&");
+        // see also: https://github.com/lodash/lodash/blob/2da024c3b4f9947a48517639de7560457cd4ec6c/escapeRegExp.js#L23
+        if (reHasRegExp.test(str)) {
+          return str.replace(reReplaceRegExp, "\\$&");
+        }
+        return str;
       } //# sourceMappingURL=escape-regexp.js.map
 
       /***/
@@ -3728,11 +3774,7 @@
       /***/
     },
 
-    /***/ 3121: /***/ function(
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) {
+    /***/ 3121: /***/ function(module, exports, __webpack_require__) {
       "use strict";
 
       function _defineProperty(obj, key, value) {
@@ -3977,7 +4019,14 @@
         );
       }
       var _default = Head;
-      exports["default"] = _default; //# sourceMappingURL=head.js.map
+      exports["default"] = _default;
+      if (
+        typeof exports.default === "function" ||
+        (typeof exports.default === "object" && exports.default !== null)
+      ) {
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
+      } //# sourceMappingURL=head.js.map
 
       /***/
     },
@@ -4397,6 +4446,7 @@
       exports["default"] = void 0;
       var _normalizeTrailingSlash = __webpack_require__(2700);
       var _routeLoader = __webpack_require__(2497);
+      var _script = __webpack_require__(3573);
       var _isError = _interopRequireWildcard(__webpack_require__(676));
       var _denormalizePagePath = __webpack_require__(4522);
       var _normalizeLocalePath = __webpack_require__(4769);
@@ -5066,6 +5116,8 @@
                     props,
                     __N_SSG,
                     __N_SSP,
+                    component,
+                    scripts,
                     destination,
                     parsedHref,
                     ref3,
@@ -5559,14 +5611,25 @@
                               (props = routeInfo.props),
                               (__N_SSG = routeInfo.__N_SSG),
                               (__N_SSP = routeInfo.__N_SSP);
+                            component = routeInfo.Component;
+                            if (component && component.unstable_scriptLoader) {
+                              scripts = [].concat(
+                                component.unstable_scriptLoader()
+                              );
+                              scripts.forEach(function(script) {
+                                (0, _script).handleClientScriptLoad(
+                                  script.props
+                                );
+                              });
+                            }
                             if (!((__N_SSG || __N_SSP) && props)) {
-                              _ctx.next = 144;
+                              _ctx.next = 146;
                               break;
                             }
                             if (
                               !(props.pageProps && props.pageProps.__N_REDIRECT)
                             ) {
-                              _ctx.next = 129;
+                              _ctx.next = 131;
                               break;
                             }
                             destination = props.pageProps.__N_REDIRECT;
@@ -5576,7 +5639,7 @@
                                 props.pageProps.__N_REDIRECT_BASE_PATH !== false
                               )
                             ) {
-                              _ctx.next = 127;
+                              _ctx.next = 129;
                               break;
                             }
                             parsedHref = (0,
@@ -5596,31 +5659,31 @@
                               "return",
                               _this.change(method, newUrl, newAs, options)
                             );
-                          case 127:
+                          case 129:
                             window.location.href = destination;
                             return _ctx.abrupt(
                               "return",
                               new Promise(function() {})
                             );
-                          case 129:
+                          case 131:
                             nextState.isPreview = !!props.__N_PREVIEW;
                             if (!(props.notFound === SSG_DATA_NOT_FOUND)) {
-                              _ctx.next = 144;
+                              _ctx.next = 146;
                               break;
                             }
-                            _ctx.prev = 132;
-                            _ctx.next = 135;
+                            _ctx.prev = 134;
+                            _ctx.next = 137;
                             return _this.fetchComponent("/404");
-                          case 135:
+                          case 137:
                             notFoundRoute = "/404";
-                            _ctx.next = 141;
+                            _ctx.next = 143;
                             break;
-                          case 138:
-                            _ctx.prev = 138;
-                            _ctx.t3 = _ctx["catch"](132);
+                          case 140:
+                            _ctx.prev = 140;
+                            _ctx.t3 = _ctx["catch"](134);
                             notFoundRoute = "/_error";
-                          case 141:
-                            _ctx.next = 143;
+                          case 143:
+                            _ctx.next = 145;
                             return _this.getRouteInfo(
                               notFoundRoute,
                               notFoundRoute,
@@ -5633,9 +5696,9 @@
                               nextState.locale,
                               nextState.isPreview
                             );
-                          case 143:
+                          case 145:
                             routeInfo = _ctx.sent;
-                          case 144:
+                          case 146:
                             Router.events.emit(
                               "beforeHistoryChange",
                               as,
@@ -5673,7 +5736,7 @@
                                   y: 0
                                 }
                               : null;
-                            _ctx.next = 153;
+                            _ctx.next = 155;
                             return _this
                               .set(
                                 _objectSpread({}, nextState, {
@@ -5692,9 +5755,9 @@
                                 if (e.cancelled) error = error || e;
                                 else throw e;
                               });
-                          case 153:
+                          case 155:
                             if (!error) {
-                              _ctx.next = 156;
+                              _ctx.next = 158;
                               break;
                             }
                             Router.events.emit(
@@ -5704,7 +5767,7 @@
                               routeProps
                             );
                             throw error;
-                          case 156:
+                          case 158:
                             if (false) {
                             }
                             Router.events.emit(
@@ -5713,8 +5776,8 @@
                               routeProps
                             );
                             return _ctx.abrupt("return", true);
-                          case 161:
-                            _ctx.prev = 161;
+                          case 163:
+                            _ctx.prev = 163;
                             _ctx.t4 = _ctx["catch"](113);
                             if (
                               !(
@@ -5722,13 +5785,13 @@
                                 _ctx.t4.cancelled
                               )
                             ) {
-                              _ctx.next = 165;
+                              _ctx.next = 167;
                               break;
                             }
                             return _ctx.abrupt("return", false);
-                          case 165:
+                          case 167:
                             throw _ctx.t4;
-                          case 166:
+                          case 168:
                           case "end":
                             return _ctx.stop();
                         }
@@ -5737,8 +5800,8 @@
                     null,
                     [
                       [39, 51],
-                      [113, 161],
-                      [132, 138]
+                      [113, 163],
+                      [134, 140]
                     ]
                   );
                 })
Diff for index.html
@@ -19,15 +19,15 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-6c28bc120ef33497.js"
+      src="/_next/static/chunks/main-ac58a1e29dd8158c.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-cf4319dec8fb8d46.js"
+      src="/_next/static/chunks/pages/_app-bfaa0e36469b32e4.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/index-a49797fad5e5a39b.js"
+      src="/_next/static/chunks/pages/index-7eff8c9e187d9f9d.js"
       defer=""
     ></script>
     <script src="/_next/static/BUILD_ID/_buildManifest.js" defer=""></script>
Diff for link.html
@@ -19,15 +19,15 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-6c28bc120ef33497.js"
+      src="/_next/static/chunks/main-ac58a1e29dd8158c.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-cf4319dec8fb8d46.js"
+      src="/_next/static/chunks/pages/_app-bfaa0e36469b32e4.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-c605640c895e01ab.js"
+      src="/_next/static/chunks/pages/link-ca5e63d57db66cd2.js"
       defer=""
     ></script>
     <script src="/_next/static/BUILD_ID/_buildManifest.js" defer=""></script>
Diff for withRouter.html
@@ -19,15 +19,15 @@
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/main-6c28bc120ef33497.js"
+      src="/_next/static/chunks/main-ac58a1e29dd8158c.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-cf4319dec8fb8d46.js"
+      src="/_next/static/chunks/pages/_app-bfaa0e36469b32e4.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/withRouter-ee616b01250df021.js"
+      src="/_next/static/chunks/pages/withRouter-04f6802cebd3d340.js"
       defer=""
     ></script>
     <script src="/_next/static/BUILD_ID/_buildManifest.js" defer=""></script>

Please sign in to comment.