Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't use ODB for routes that match middleware #1171

Merged
merged 7 commits into from
Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 1 addition & 10 deletions demos/default/local-plugin/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { useRouter } from 'next/router'
import Link from 'next/link'

const Show = ({ show }) => {
const router = useRouter()

// This is never shown on Netlify. We just need it for NextJS to be happy,
// because NextJS will render a fallback HTML page.
if (router.isFallback) {
return <div>Loading...</div>
}

return (
<div>
<p>
Check the network panel for the header <code>x-middleware-date</code> to ensure that it is running
</p>

<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
)
}

export async function getStaticPaths() {
// Set the paths we want to pre-render
const paths = [{ params: { slug: ['my', 'path', '1'] } }, { params: { slug: ['my', 'path', '2'] } }]

// We'll pre-render these paths at build time.
// { fallback: true } means other routes will be rendered at runtime.
return { paths, fallback: true }
}

export async function getStaticProps({ params }) {
// The ID to render
const { slug } = params
const id = slug[slug.length - 1]

const res = await fetch(`https://api.tvmaze.com/shows/${id}`)
const data = await res.json()

return {
props: {
show: data,
},
}
}

export default Show
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useRouter } from 'next/router'
import Link from 'next/link'

const Show = ({ show }) => {
const router = useRouter()

// This is never shown on Netlify. We just need it for NextJS to be happy,
// because NextJS will render a fallback HTML page.
if (router.isFallback) {
return <div>Loading...</div>
}

return (
<div>
<p>
Check the network panel for the header <code>x-middleware-date</code> to ensure that it is running
</p>
<hr />

<h1>Show #{show.id}</h1>
<p>{show.name}</p>

<hr />

<Link href="/">
<a>Go back home</a>
</Link>
</div>
)
}

export async function getStaticPaths() {
// Set the paths we want to pre-render
const paths = [{ params: { id: '3' } }, { params: { id: '4' } }]

// We'll pre-render these paths at build time.
// { fallback: true } means other routes will be rendered at runtime.
return { paths, fallback: true }
}

export async function getStaticProps({ params }) {
// The ID to render
const { id } = params

const res = await fetch(`https://api.tvmaze.com/shows/${id}`)
const data = await res.json()

return {
props: {
show: data,
},
}
}

export default Show
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { NextResponse } from 'next/server'

export function middleware() {
const res = NextResponse.next()
res.headers.set('x-middleware-date', new Date().toISOString())
return res
}
18 changes: 14 additions & 4 deletions demos/default/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ const Index = ({ shows, nodeEnv }) => {

return (
<div>
<img src="/next-on-netlify.png" alt="NextJS on Netlify Banner" className='self-center w-full max-h-80 max-w-5xl m-auto' />
<img
src="/next-on-netlify.png"
alt="NextJS on Netlify Banner"
className="self-center w-full max-h-80 max-w-5xl m-auto"
/>

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

<p>
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.
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.
</p>
<code>NODE_ENV: {nodeEnv}</code>

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

<h2>Localization</h2>
<p>
Localization (i18n) is supported! This demo uses <code>fr</code> with <code>en</code> as the default locale (at{' '}
<code>/</code>).
Localization (i18n) is supported! This demo uses <code>fr</code> with <code>en</code> as the default locale
(at <code>/</code>).
</p>
<strong>The current locale is {locale}</strong>
<p>Click on the links below to see the above text change</p>
Expand Down Expand Up @@ -175,6 +180,11 @@ const Index = ({ shows, nodeEnv }) => {
<a>Middleware</a>
</Link>
</li>
<li>
<Link href="/getStaticProps/withFallbackAndMiddleware/4">
<a>Middleware matching a pre-rendered dynamic route</a>
</Link>
</li>
</ul>
<h4>Preview mode</h4>
<p>Preview mode: </p>
Expand Down
19 changes: 11 additions & 8 deletions src/helpers/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ export const matchesRewrite = (file: string, rewrites: Rewrites): boolean => {
return matchesRedirect(file, rewrites.beforeFiles)
}

export const getMiddleware = async (publish: string): Promise<Array<string>> => {
const manifestPath = join(publish, 'server', 'middleware-manifest.json')
if (existsSync(manifestPath)) {
const manifest = await readJson(manifestPath, { throws: false })
return manifest?.sortedMiddleware ?? []
}
return []
}

// eslint-disable-next-line max-lines-per-function
export const moveStaticPages = async ({
netlifyConfig,
Expand All @@ -75,14 +84,8 @@ export const moveStaticPages = async ({
const dataDir = join('_next', 'data', buildId)
await ensureDir(dataDir)
// Load the middleware manifest so we can check if a file matches it before moving
let middleware
const manifestPath = join(outputDir, 'middleware-manifest.json')
if (existsSync(manifestPath)) {
const manifest = await readJson(manifestPath)
if (manifest?.middleware) {
middleware = Object.keys(manifest.middleware).map((path) => path.slice(1))
}
}
const middlewarePaths = await getMiddleware(netlifyConfig.build.publish)
const middleware = middlewarePaths.map((path) => path.slice(1))

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