Skip to content

Commit bbcdfbd

Browse files
fix: don't use ODB for routes that match middleware (#1171)
* fix: don't use ODB for routes that match middleware * chore: fix duplicate rules * chore: changes from review * chore: add return types Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
1 parent bf4d309 commit bbcdfbd

File tree

9 files changed

+461
-91
lines changed

9 files changed

+461
-91
lines changed

demos/default/local-plugin/package-lock.json

+1-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { useRouter } from 'next/router'
2+
import Link from 'next/link'
3+
4+
const Show = ({ show }) => {
5+
const router = useRouter()
6+
7+
// This is never shown on Netlify. We just need it for NextJS to be happy,
8+
// because NextJS will render a fallback HTML page.
9+
if (router.isFallback) {
10+
return <div>Loading...</div>
11+
}
12+
13+
return (
14+
<div>
15+
<p>
16+
Check the network panel for the header <code>x-middleware-date</code> to ensure that it is running
17+
</p>
18+
19+
<hr />
20+
21+
<h1>Show #{show.id}</h1>
22+
<p>{show.name}</p>
23+
24+
<hr />
25+
26+
<Link href="/">
27+
<a>Go back home</a>
28+
</Link>
29+
</div>
30+
)
31+
}
32+
33+
export async function getStaticPaths() {
34+
// Set the paths we want to pre-render
35+
const paths = [{ params: { slug: ['my', 'path', '1'] } }, { params: { slug: ['my', 'path', '2'] } }]
36+
37+
// We'll pre-render these paths at build time.
38+
// { fallback: true } means other routes will be rendered at runtime.
39+
return { paths, fallback: true }
40+
}
41+
42+
export async function getStaticProps({ params }) {
43+
// The ID to render
44+
const { slug } = params
45+
const id = slug[slug.length - 1]
46+
47+
const res = await fetch(`https://api.tvmaze.com/shows/${id}`)
48+
const data = await res.json()
49+
50+
return {
51+
props: {
52+
show: data,
53+
},
54+
}
55+
}
56+
57+
export default Show
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { useRouter } from 'next/router'
2+
import Link from 'next/link'
3+
4+
const Show = ({ show }) => {
5+
const router = useRouter()
6+
7+
// This is never shown on Netlify. We just need it for NextJS to be happy,
8+
// because NextJS will render a fallback HTML page.
9+
if (router.isFallback) {
10+
return <div>Loading...</div>
11+
}
12+
13+
return (
14+
<div>
15+
<p>
16+
Check the network panel for the header <code>x-middleware-date</code> to ensure that it is running
17+
</p>
18+
<hr />
19+
20+
<h1>Show #{show.id}</h1>
21+
<p>{show.name}</p>
22+
23+
<hr />
24+
25+
<Link href="/">
26+
<a>Go back home</a>
27+
</Link>
28+
</div>
29+
)
30+
}
31+
32+
export async function getStaticPaths() {
33+
// Set the paths we want to pre-render
34+
const paths = [{ params: { id: '3' } }, { params: { id: '4' } }]
35+
36+
// We'll pre-render these paths at build time.
37+
// { fallback: true } means other routes will be rendered at runtime.
38+
return { paths, fallback: true }
39+
}
40+
41+
export async function getStaticProps({ params }) {
42+
// The ID to render
43+
const { id } = params
44+
45+
const res = await fetch(`https://api.tvmaze.com/shows/${id}`)
46+
const data = await res.json()
47+
48+
return {
49+
props: {
50+
show: data,
51+
},
52+
}
53+
}
54+
55+
export default Show
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { NextResponse } from 'next/server'
2+
3+
export function middleware() {
4+
const res = NextResponse.next()
5+
res.headers.set('x-middleware-date', new Date().toISOString())
6+
return res
7+
}

demos/default/pages/index.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ const Index = ({ shows, nodeEnv }) => {
88

99
return (
1010
<div>
11-
<img src="/next-on-netlify.png" alt="NextJS on Netlify Banner" className='self-center w-full max-h-80 max-w-5xl m-auto' />
11+
<img
12+
src="/next-on-netlify.png"
13+
alt="NextJS on Netlify Banner"
14+
className="self-center w-full max-h-80 max-w-5xl m-auto"
15+
/>
1216

1317
<div>
1418
<Header />
@@ -18,7 +22,8 @@ const Index = ({ shows, nodeEnv }) => {
1822
<h2>Server-Side Rendering</h2>
1923

2024
<p>
21-
This page is server-side rendered. It fetches a random list of five TV shows from the TVmaze REST API. Refresh this page to see it change.
25+
This page is server-side rendered. It fetches a random list of five TV shows from the TVmaze REST API. Refresh
26+
this page to see it change.
2227
</p>
2328
<code>NODE_ENV: {nodeEnv}</code>
2429

@@ -86,8 +91,8 @@ const Index = ({ shows, nodeEnv }) => {
8691

8792
<h2>Localization</h2>
8893
<p>
89-
Localization (i18n) is supported! This demo uses <code>fr</code> with <code>en</code> as the default locale (at{' '}
90-
<code>/</code>).
94+
Localization (i18n) is supported! This demo uses <code>fr</code> with <code>en</code> as the default locale
95+
(at <code>/</code>).
9196
</p>
9297
<strong>The current locale is {locale}</strong>
9398
<p>Click on the links below to see the above text change</p>
@@ -175,6 +180,11 @@ const Index = ({ shows, nodeEnv }) => {
175180
<a>Middleware</a>
176181
</Link>
177182
</li>
183+
<li>
184+
<Link href="/getStaticProps/withFallbackAndMiddleware/4">
185+
<a>Middleware matching a pre-rendered dynamic route</a>
186+
</Link>
187+
</li>
178188
</ul>
179189
<h4>Preview mode</h4>
180190
<p>Preview mode: </p>

src/helpers/files.ts

+11-8
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ export const matchesRewrite = (file: string, rewrites: Rewrites): boolean => {
5858
return matchesRedirect(file, rewrites.beforeFiles)
5959
}
6060

61+
export const getMiddleware = async (publish: string): Promise<Array<string>> => {
62+
const manifestPath = join(publish, 'server', 'middleware-manifest.json')
63+
if (existsSync(manifestPath)) {
64+
const manifest = await readJson(manifestPath, { throws: false })
65+
return manifest?.sortedMiddleware ?? []
66+
}
67+
return []
68+
}
69+
6170
// eslint-disable-next-line max-lines-per-function
6271
export const moveStaticPages = async ({
6372
netlifyConfig,
@@ -75,14 +84,8 @@ export const moveStaticPages = async ({
7584
const dataDir = join('_next', 'data', buildId)
7685
await ensureDir(dataDir)
7786
// Load the middleware manifest so we can check if a file matches it before moving
78-
let middleware
79-
const manifestPath = join(outputDir, 'middleware-manifest.json')
80-
if (existsSync(manifestPath)) {
81-
const manifest = await readJson(manifestPath)
82-
if (manifest?.middleware) {
83-
middleware = Object.keys(manifest.middleware).map((path) => path.slice(1))
84-
}
85-
}
87+
const middlewarePaths = await getMiddleware(netlifyConfig.build.publish)
88+
const middleware = middlewarePaths.map((path) => path.slice(1))
8689

8790
const prerenderManifest: PrerenderManifest = await readJson(
8891
join(netlifyConfig.build.publish, 'prerender-manifest.json'),

0 commit comments

Comments
 (0)