Skip to content

Commit

Permalink
Add with-edgedb example (#35929)
Browse files Browse the repository at this point in the history
## Documentation / Examples
 
- [X] Make sure the linting passes by running `yarn lint`
  • Loading branch information
colinhacks authored Apr 27, 2022
1 parent 89a4c16 commit 842e4ec
Show file tree
Hide file tree
Showing 21 changed files with 958 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/with-edgedb/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dbschema/edgeql-js
38 changes: 38 additions & 0 deletions examples/with-edgedb/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
.vscode
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel

# query builder
dbschema/edgeql-js
150 changes: 150 additions & 0 deletions examples/with-edgedb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Full-stack EdgeDB + Next.js application

A simple blog application built with Next.js, TypeScript, [React](https://reactjs.org/), and [EdgeDB](https://www.edgedb.com/docs) on the backend.

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-edgedb&project-name=with-edgedb&repository-name=with-edgedb&env=EDGEDB_DSN)

## How to use

### Download the example project

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:

```bash
npx create-next-app --example with-edgedb with-edgedb-app
# or
yarn create next-app --example with-edgedb with-edgedb-app
# or
pnpm create next-app -- --example with-edgedb with-edgedb-app
```

Then `cd` into the created directory.

```bash
$ cd with-edgedb-app
```

### Install the CLI

First install the EdgeDB CLI if you haven't already.

```bash
# macOS/Linux
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.edgedb.com | sh

# Windows (Powershell)
$ iwr https://ps1.edgedb.com -useb | iex
```

### Initialize the EdgeDB project

Initialize the project with the following CLI command:

```bash
$ edgedb project init
```

After you follow the prompts, this command will spin up a local EdgeDB instance and apply all the migrations inside `dbschema/migrations`. Now that the project is initialized, all EdgeDB clients initialized inside the project directory will connect to this instance automatically—no need for environment variables or hard-coded configuration. ([Read more about projects here.](https://www.edgedb.com/docs/guides/projects))

### Install dependencies

Install npm dependencies:

```bash
$ npm install
# or
$ yarn
```

### Generate the query builder

This project uses the EdgeQL query builder for TypeScript. This tool can express any EdgeQL query in a code-first way and infers a static return type. Generate it with the following command:

```bash
$ npx edgeql-js
```

The query builder consists of several files that are generated into the `dbschema/edgeql-js` directory. Import it like so:

```ts
import e from './dbschema/edgeql-js'
```

### Seed the database

```bash
$ npx ts-node seed.ts
```

### Start the app

```bash
$ yarn dev
```

The application should now be running on http://localhost:3000.

## Notes

#### packages structure

- `/`: See all published posts
- `/drafts`: See all drafts
- `/create`: Form to create new draft
- `/blog/:id`: See either an edit page or a published post, depending on the publish status of the post.

#### API structure

- `POST /api/post`: Create a new post
- Body: `{title: string; content: string; authorName: string}`
- `PATCH /api/post/:id`: Update a post by `id`
- Body: `{title?: string; content?: string;}`
- `PUT /api/publish/:id`: Publish a post by `id`
- `DELETE /api/post/:id`: Delete a post by `id`

## Evolving the app

Evolving the application typically requires three steps:

1. Update the schema in `dbschema/default.esdl`
2. Generate a new migration with `edgedb migration create`
3. Apply the migration with `edgedb migrate`
4. Regenerate the query builder with `npx edgeql-js`
5. Update the application code, as needed.

## Deployment

To deploy this application, deploy EdgeDB to your preferred cloud provider:

- [AWS](https://www.edgedb.com/docs/guides/deployment/aws_aurora_ecs)
- [Google Cloud](https://www.edgedb.com/docs/guides/deployment/gcp)
- [Azure](https://www.edgedb.com/docs/guides/deployment/azure_flexibleserver)
- [DigitalOcean](https://www.edgedb.com/docs/guides/deployment/digitalocean)
- [Fly.io](https://www.edgedb.com/docs/guides/deployment/fly_io)
- [Docker](https://www.edgedb.com/docs/guides/deployment/docker) (cloud-agnostic)

Then:

1. Find your instance's DSN (AKA connection string). The exact instructions for this depend on which cloud you are deploying to.

2. Use this DSN to migrate your remote instance to the latest schema. Run this command from inside your project directory.

```
edgedb migrate --dsn <your-instance-dsn> --tls-security insecure
```

You have to disable TLS checks with `--tls-security insecure`. All EdgeDB instances use TLS by default, but configuring it is out of scope of this project.

3. Deploy this app to Vercel with the button above. You'll be prompted to provide a value for `EDGEDB_DSN`, the value from the previous step.

4. Open the application at the deployment URL supplied by Vercel.

## Next steps

- Check out the [EdgeDB docs](https://www.edgedb.com/docs)
- Join the EdgeDB [Discord server](https://edgedb.com/p/discord)
- Check out the code on [GitHub](https://github.com/edgedb/edgedb)
9 changes: 9 additions & 0 deletions examples/with-edgedb/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createClient } from 'edgedb'
import e from './dbschema/edgeql-js'

// reads value of EDGEDB_DSN automatically
export const client = createClient({
// TLS configuration is beyond the scope of this example project
tlsSecurity: 'insecure',
})
export { e }
55 changes: 55 additions & 0 deletions examples/with-edgedb/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react'
import Link from 'next/link'

const Header: React.FC = () => {
return (
<nav>
<div className="left">
<Link href="/">
<a>Blog</a>
</Link>
<Link href="/drafts">
<a>Drafts</a>
</Link>
</div>
<div className="right">
<Link href="/create">
<a>+ New draft</a>
</Link>
</div>
<style jsx>{`
nav {
display: flex;
padding: 2rem;
align-items: center;
}
.bold {
font-weight: bold;
}
a {
text-decoration: none;
color: #000;
display: inline-block;
}
a + a {
margin-left: 1rem;
}
.right {
margin-left: auto;
}
.right a {
border: 2px solid black;
padding: 0.5rem 1rem;
border-radius: 3px;
}
`}</style>
</nav>
)
}

export default Header
51 changes: 51 additions & 0 deletions examples/with-edgedb/components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { ReactNode } from 'react'
import Header from './Header'

type Props = {
children: ReactNode
}

const Layout: React.FC<Props> = (props) => (
<div style={{ paddingBottom: '30px' }}>
<Header />
<div className="layout">{props.children}</div>
<style jsx global>{`
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol';
background: rgba(0, 0, 0, 0);
}
input,
textarea,
button {
font-size: 16px;
}
button {
cursor: pointer;
}
`}</style>
<style jsx>{`
.layout {
padding: 0 2rem;
}
`}</style>
</div>
)

export default Layout
40 changes: 40 additions & 0 deletions examples/with-edgedb/components/Post.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react'
import ReactMarkdown from 'react-markdown'
import Link from 'next/link'
import { PostProps } from '../pages/blog/[id]'

const Post: React.FC<{ post: PostProps }> = ({ post }) => {
return (
<Link href={`/blog/${post.id}`} passHref>
<div>
<h2>{post.title}</h2>
<small>By {post.authorName}</small>
<br />
<br />
<ReactMarkdown className={'react-markdown'}>
{post.content || ''}
</ReactMarkdown>
<style jsx>{`
div {
color: inherit;
padding: 2rem;
cursor: pointer;
}
h2 {
margin: 0px;
padding-bottom: 4px;
}
small {
color: #888;
}
.react-markdown,
.react-markdown > p {
margin: 0px;
}
`}</style>
</div>
</Link>
)
}

export default Post
11 changes: 11 additions & 0 deletions examples/with-edgedb/dbschema/default.esdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module default {

type Post {
required property title -> str;
required property content -> str { default := '' };
required property authorName -> str { default := 'Unknown author' };
property published -> datetime;
property publishedISO := <str>.published;
}

}
15 changes: 15 additions & 0 deletions examples/with-edgedb/dbschema/migrations/00001.edgeql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CREATE MIGRATION m1gcnribdubi476w7daqzhuxvbutfpiqyhhbm2nyfv3xhzc6z757ia
ONTO initial
{
CREATE TYPE default::Post {
CREATE REQUIRED PROPERTY authorName -> std::str {
SET default := 'Unknown author';
};
CREATE REQUIRED PROPERTY content -> std::str {
SET default := '';
};
CREATE PROPERTY published -> std::datetime;
CREATE PROPERTY publishedISO := (<std::str>.published);
CREATE REQUIRED PROPERTY title -> std::str;
};
};
2 changes: 2 additions & 0 deletions examples/with-edgedb/edgedb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[edgedb]
server-version = "1.2"
5 changes: 5 additions & 0 deletions examples/with-edgedb/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
Loading

1 comment on commit 842e4ec

@ijjk
Copy link
Member

@ijjk ijjk commented on 842e4ec Apr 27, 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.7s ⚠️ +44ms
buildDurationCached 5.8s 5.9s ⚠️ +118ms
nodeModulesSize 86.9 MB 87.4 MB ⚠️ +502 kB
Page Load Tests Overall increase ✓
vercel/next.js canary v12.1.5 vercel/next.js refs/heads/canary Change
/ failed reqs 0 0
/ total time (seconds) 3.15 3.143 -0.01
/ avg req/sec 793.57 795.42 +1.85
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.416 1.4 -0.02
/error-in-render avg req/sec 1765.25 1785.21 +19.96
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 ⚠️ +317 B
webpack-HASH.js gzip 1.44 kB 1.44 kB
Overall change 72 kB 72.3 kB ⚠️ +317 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.73 kB ⚠️ +4 B
index-HASH.js gzip 263 B 263 B
link-HASH.js gzip 2.36 kB 2.63 kB ⚠️ +265 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 ⚠️ +306 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 532 B 533 B ⚠️ +1 B
link.html gzip 546 B 546 B
withRouter.html gzip 527 B 527 B
Overall change 1.6 kB 1.61 kB ⚠️ +1 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-bfb178f7d6259a9d.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-b2c86b9b6041c9a3.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"
           ]);
@@ -893,6 +891,7 @@
           onLoadingCompleteRef = _param.onLoadingCompleteRef,
           setBlurComplete = _param.setBlurComplete,
           setIntersection = _param.setIntersection,
+          onLoad = _param.onLoad,
           onError = _param.onError,
           isVisible = _param.isVisible,
           rest = _objectWithoutProperties(_param, [
@@ -914,6 +913,7 @@
             "onLoadingCompleteRef",
             "setBlurComplete",
             "setIntersection",
+            "onLoad",
             "onError",
             "isVisible"
           ]);
@@ -972,6 +972,9 @@
                     onLoadingCompleteRef,
                     setBlurComplete
                   );
+                  if (onLoad) {
+                    onLoad(event);
+                  }
                 },
                 onError: function(event) {
                   if (placeholder === "blur") {
@@ -1388,7 +1391,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;
@@ -164,6 +192,11 @@
         });
       }
       function Link(props) {
+        var _legacyBehavior = props.legacyBehavior,
+          legacyBehavior =
+            _legacyBehavior === void 0
+              ? Boolean(false) !== true
+              : _legacyBehavior;
         if (false) {
           var hasWarned,
             optionalProps,
@@ -172,48 +205,72 @@
             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;
         var ref1 = _slicedToArray(
             (0, _useIntersection).useIntersection({
               rootMargin: "200px"
@@ -232,14 +289,14 @@
               previousHref.current = href;
             }
             setIntersectionRef(el);
-            if (childRef) {
+            if (legacyBehavior && childRef) {
               if (typeof childRef === "function") childRef(el);
               else if (typeof childRef === "object") {
                 childRef.current = el;
               }
             }
           },
-          [as, childRef, href, resetVisible, setIntersectionRef]
+          [as, childRef, href, resetVisible, setIntersectionRef, legacyBehavior]
         );
         _react.default.useEffect(
           function() {
@@ -262,7 +319,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 +341,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,7 +390,13 @@
               )
             );
         }
-        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;
@@ -608,7 +686,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.11";
       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-d49dd75f151b9b34.js"
+      src="/_next/static/chunks/main-93ee88eff6d9a601.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-71642a8ccc3189c6.js"
+      src="/_next/static/chunks/pages/_app-6bc74693935b0e21.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-d49dd75f151b9b34.js"
+      src="/_next/static/chunks/main-93ee88eff6d9a601.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-71642a8ccc3189c6.js"
+      src="/_next/static/chunks/pages/_app-6bc74693935b0e21.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-c605640c895e01ab.js"
+      src="/_next/static/chunks/pages/link-b2c86b9b6041c9a3.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-d49dd75f151b9b34.js"
+      src="/_next/static/chunks/main-93ee88eff6d9a601.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-71642a8ccc3189c6.js"
+      src="/_next/static/chunks/pages/_app-6bc74693935b0e21.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 11.6s 11.9s ⚠️ +266ms
buildDurationCached 6.2s 6.2s ⚠️ +17ms
nodeModulesSize 86.9 MB 87.4 MB ⚠️ +502 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.171 3.178 ⚠️ +0.01
/ avg req/sec 788.41 786.55 ⚠️ -1.86
/error-in-render failed reqs 0 0
/error-in-render total time (seconds) 1.371 1.403 ⚠️ +0.03
/error-in-render avg req/sec 1824.1 1782.37 ⚠️ -41.73
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.78 kB ⚠️ +3 B
index-HASH.js gzip 261 B 261 B
link-HASH.js gzip 2.44 kB 2.74 kB ⚠️ +305 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.4 kB ⚠️ +368 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 456 B -3 B
Overall change 459 B 456 B -3 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 530 B ⚠️ +1 B
link.html gzip 542 B 544 B ⚠️ +2 B
withRouter.html gzip 524 B 526 B ⚠️ +2 B
Overall change 1.59 kB 1.6 kB ⚠️ +5 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-bfb178f7d6259a9d.js"],
+  "/link": ["static\u002Fchunks\u002Fpages\u002Flink-b2c86b9b6041c9a3.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"
           ]);
@@ -893,6 +891,7 @@
           onLoadingCompleteRef = _param.onLoadingCompleteRef,
           setBlurComplete = _param.setBlurComplete,
           setIntersection = _param.setIntersection,
+          onLoad = _param.onLoad,
           onError = _param.onError,
           isVisible = _param.isVisible,
           rest = _objectWithoutProperties(_param, [
@@ -914,6 +913,7 @@
             "onLoadingCompleteRef",
             "setBlurComplete",
             "setIntersection",
+            "onLoad",
             "onError",
             "isVisible"
           ]);
@@ -972,6 +972,9 @@
                     onLoadingCompleteRef,
                     setBlurComplete
                   );
+                  if (onLoad) {
+                    onLoad(event);
+                  }
                 },
                 onError: function(event) {
                   if (placeholder === "blur") {
@@ -1388,7 +1391,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;
@@ -164,6 +192,11 @@
         });
       }
       function Link(props) {
+        var _legacyBehavior = props.legacyBehavior,
+          legacyBehavior =
+            _legacyBehavior === void 0
+              ? Boolean(false) !== true
+              : _legacyBehavior;
         if (false) {
           var hasWarned,
             optionalProps,
@@ -172,48 +205,72 @@
             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;
         var ref1 = _slicedToArray(
             (0, _useIntersection).useIntersection({
               rootMargin: "200px"
@@ -232,14 +289,14 @@
               previousHref.current = href;
             }
             setIntersectionRef(el);
-            if (childRef) {
+            if (legacyBehavior && childRef) {
               if (typeof childRef === "function") childRef(el);
               else if (typeof childRef === "object") {
                 childRef.current = el;
               }
             }
           },
-          [as, childRef, href, resetVisible, setIntersectionRef]
+          [as, childRef, href, resetVisible, setIntersectionRef, legacyBehavior]
         );
         _react.default.useEffect(
           function() {
@@ -262,7 +319,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 +341,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,7 +390,13 @@
               )
             );
         }
-        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;
@@ -608,7 +686,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.11";
       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-d49dd75f151b9b34.js"
+      src="/_next/static/chunks/main-93ee88eff6d9a601.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-71642a8ccc3189c6.js"
+      src="/_next/static/chunks/pages/_app-6bc74693935b0e21.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-d49dd75f151b9b34.js"
+      src="/_next/static/chunks/main-93ee88eff6d9a601.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-71642a8ccc3189c6.js"
+      src="/_next/static/chunks/pages/_app-6bc74693935b0e21.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/link-c605640c895e01ab.js"
+      src="/_next/static/chunks/pages/link-b2c86b9b6041c9a3.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-d49dd75f151b9b34.js"
+      src="/_next/static/chunks/main-93ee88eff6d9a601.js"
       defer=""
     ></script>
     <script
-      src="/_next/static/chunks/pages/_app-71642a8ccc3189c6.js"
+      src="/_next/static/chunks/pages/_app-6bc74693935b0e21.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.