next-static-manifest
Create a static page manifest of your Next.js exported html pages, allowing you to match incoming requests with dynamic Next.js HTML routes.
Installation
$ npm install --save next-static-manifest
$ yarn add next-static-manifest
Usage
Let's take a look at this scenario, our application looks like this:
|-- pages
| |-- index.js
| |-- [...slug].js
| |-- blog/posts/[id].js
| |-- blog/posts/[id]/[authorId].js
We add next-static-manifest to our export script:
$ next build && next export && next-static-manifest
And after exporting our app, we get this:
|-- out
| |-- next-static-manifest.json
| |-- index.html
| |-- [...slug].html
| |-- blog/posts/[id].html
| |-- blog/posts/[id]/[authorId].html
The next-static-manifest.json
will look this:
[
{
"src": "/blog/posts/[id]/[authorId]",
"dest": "/blog/posts/[id]/[authorId].html",
"regex": "__REGEXP__:/^\\/blog\\/posts\\/([^/]+?)\\/([^/]+?)(?:\\/)?$/",
"dynamic": true
},
{
"src": "/blog/posts/[id]",
"dest": "/blog/posts/[id].html",
"regex": "__REGEXP__:/^\\/blog\\/posts\\/([^/]+?)(?:\\/)?$/",
"dynamic": true
},
{
"src": "/index",
"dest": "/index.html",
"regex": "__REGEXP__:/^\\/index(?:\\/)?$/",
"dynamic": false
},
{
"src": "/404",
"dest": "/404.html",
"regex": "__REGEXP__:/^\\/404(?:\\/)?$/",
"dynamic": false
},
{
"dynamic": false,
"regex": "__REGEXP__:/^\\/(?:\\/)?$/",
"src": "/",
"dest": "index.html"
},
{
"src": "/[...slug]",
"dest": "/[...slug].html",
"regex": "__REGEXP__:/^\\/(.+?)(?:\\/)?$/",
"dynamic": true
}
]
Without any type of infrastructure in place, we can't route users to our dynamically exported routes.
A request to: /blog/posts/123-456-789
wont match our filesystem location for the /blog/posts/[id].html
file.
However, if we write a small Lambda@Edge function or use a Worker to ingest this file, we can automatically route users to the correct .html
entrypoint.
How it works
next-static-manifest
runs after your app has been exported by Next. We generate a next-static-manifest.json
file that you can poll on Lambda@Edge or in your Worker, after deploying, your worker will get a new file and route accordingly.
In your function/worker, it's important to use decode
when parsing the manifest file.
import { decode } from 'next-static-manifest';
fetch('.../next-static-manifest.json')
.then((r) => r.json())
.then((data) => decode(data));
We need to hydrate our data with decode
, because regex isn't part of the JSON spec, so we have to encode/decode it ourselves.
Questions? Feedback? Please let me know
License (MIT)
WWWWWW||WWWWWW
W W W||W W W
||
( OO )__________
/ | \
/o o| MIT \
\___/||_||__||_|| *
|| || || ||
_||_|| _||_||
(__|__|(__|__|
Copyright © 2020-present Jack Hanford, jackhanford@gmail.com