Skip to content

Commit 7ec7e3e

Browse files
ijjkTooTallNate
andauthoredAug 11, 2022
[build-output-api] Update On-Demand ISR example with expiration: false prerenders (vercel#374)
* Update On-Demand ISR example with expiration: false prerenders * Apply suggestions from code review Co-authored-by: Nathan Rajlich <[email protected]> * Add revalidate link * fix match Co-authored-by: Nathan Rajlich <[email protected]>

13 files changed

+129
-2
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
{
2-
"version": 3
2+
"version": 3,
3+
"routes": [
4+
{ "handle": "filesystem" },
5+
{
6+
"src": "/blog/(?<slug>[^/]+)(?:/)?",
7+
"dest": "/blog/[slug]?slug=$slug"
8+
}
9+
]
310
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>404 | Not Found</title>
5+
</head>
6+
<body>
7+
<h1>Not Found</h1>
8+
9+
<!-- Authentication example is for demo purposes only. In a production system, use better authentication strategies. -->
10+
<p><a href="#">Generate this path via On-Demand ISR</a></p>
11+
<script>document.querySelector('a').href = `/revalidate?path=${encodeURIComponent(window.location.pathname)}&authToken=a13f94f6-a441-47ca-95fc-9f44f3450295`</script>
12+
</body>
13+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"runtime": "nodejs16.x",
3+
"handler": "index.js",
4+
"launcherType": "Nodejs"
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
const { parse } = require('querystring')
2+
3+
module.exports = (req, res) => {
4+
const matches = parse(req.headers['x-now-route-matches'])
5+
let { slug } = matches
6+
7+
// if slug isn't present in x-now-route-matches it
8+
// matched at the filesystem level and can be parsed
9+
// from the URL
10+
if (!slug) {
11+
const matches = req.url.match(/\/blog\/([^/]+)(?:\/)?/)
12+
slug = matches[1]
13+
}
14+
15+
res.setHeader('Content-Type', 'text/html; charset=utf-8')
16+
res.end(`
17+
<!DOCTYPE html>
18+
<html>
19+
<head>
20+
<title>My blog | ${slug}</title>
21+
</head>
22+
<body>
23+
<h1>Post: ${slug}</h1>
24+
<p>Generated time: ${new Date().toISOString()}</p>
25+
26+
<p>This demonstrates a SSG blog that restricts generating new paths via On-Demand ISR instead of allowing any visited paths to generate a new path.</p>
27+
28+
<p>It works by leveraging \`expiration: false\` on a prerender to only allow generating new paths when the revalidate token is provided.</p>
29+
30+
<!-- Authentication example is for demo purposes only. In a production system, use better authentication strategies. -->
31+
<p><a href="/revalidate?path=/blog/${slug}&authToken=a13f94f6-a441-47ca-95fc-9f44f3450295">Revalidate this path via On-Demand ISR</a></p>
32+
</body>
33+
</html>
34+
`)
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"expiration": false,
3+
"group": 3,
4+
"bypassToken": "87734ad8259d67c3c11747d3e4e112d0",
5+
"allowQuery": ["slug"],
6+
"fallback": "404.prerender-fallback.html"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[slug].func
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"expiration": false,
3+
"group": 3,
4+
"bypassToken": "87734ad8259d67c3c11747d3e4e112d0",
5+
"allowQuery": ["slug"],
6+
"fallback": "post-1.prerender-fallback.html"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>My blog | post-1</title>
5+
</head>
6+
<body>
7+
<h1>Post: post-1</h1>
8+
<p>Generated time: 2022-08-11T15:12:34.656Z</p>
9+
10+
<p>This demonstrates a SSG blog that restricts generating new paths via On-Demand ISR instead of allowing any visited paths to generate a new path.</p>
11+
12+
<p>It works by leveraging `expiration: false` on a prerender to only allow generating new paths when the revalidate token is provided.</p>
13+
14+
<!-- Authentication example is for demo purposes only. In a production system, use better authentication strategies. -->
15+
<p><a href="/revalidate?path=/blog/post-1&authToken=a13f94f6-a441-47ca-95fc-9f44f3450295">Revalidate this path via On-Demand ISR</a></p>
16+
</body>
17+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[slug].func
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"expiration": false,
3+
"group": 3,
4+
"bypassToken": "87734ad8259d67c3c11747d3e4e112d0",
5+
"allowQuery": ["slug"],
6+
"fallback": "post-2.prerender-fallback.html"
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>My blog | post-2</title>
5+
</head>
6+
<body>
7+
<h1>Post: post-2</h1>
8+
<p>Generated time: 2022-08-11T15:12:34.656Z</p>
9+
10+
<p>This demonstrates a SSG blog that restricts generating new paths via On-Demand ISR instead of allowing any visited paths to generate a new path.</p>
11+
12+
<p>It works by leveraging `expiration: false` on a prerender to only allow generating new paths when the revalidate token is provided.</p>
13+
14+
<!-- Authentication example is for demo purposes only. In a production system, use better authentication strategies. -->
15+
<p><a href="/revalidate?path=/blog/post-2&authToken=a13f94f6-a441-47ca-95fc-9f44f3450295">Revalidate this path via On-Demand ISR</a></p>
16+
</body>
17+
</html>

‎build-output-api/on-demand-isr/.vercel/output/functions/revalidate.func/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ module.exports = (req, res) => {
6060
res.end(`
6161
<h1>Cache for "${pathToRevalidate}" Revalidated!</h1>
6262
<p>Redirecting you back.</p>
63-
<meta http-equiv="refresh" content="2 url=${deployedUrl}">
63+
<meta http-equiv="refresh" content="2 url=${deployedUrl}${pathToRevalidate}">
6464
`)
6565
}).catch((error) => {
6666
console.error(error.stack)

‎build-output-api/on-demand-isr/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ In this demo, you can see this happening with two paths: `/` and `/data`.
3333

3434
When the revalidation is triggered, the cache will be revalidated, bypassing any caching that Vercel would normally provide.
3535

36+
There is also an example of a blog that only generates new paths when triggered via On-Demand ISR with two initial posts that are prerendered.
37+
38+
- `/blog/[slug]`
39+
- base post prerender that allows generating news paths via On-Demand ISR
40+
- [bypassToken](./.vercel/output/functions/index.prerender-config.json#L4)
41+
- `/blog/post-1`
42+
- `/blog/post-2`
43+
- initial prerendered blog posts
44+
- [bypassToken](./.vercel/output/functions/index.prerender-config.json#L4)
45+
3646
### Security
3747

3848
#### `bypassToken`

0 commit comments

Comments
 (0)
Please sign in to comment.