From 0815502017b221cc8ea5922736a2dd01c6a8819a Mon Sep 17 00:00:00 2001 From: Marc LeBlanc <7050295+marcleblanc2@users.noreply.github.com> Date: Sun, 6 Sep 2026 01:36:56 -0600 Subject: [PATCH 1/2] fix: return a real HTTP 404 for unknown doc pages generateStaticParams returned {params: {slug}} (Pages Router shape), so the App Router ignored it: no doc page was prerendered and every request rendered on demand. notFound() then fired inside the root layout's , after the response had started streaming, so missing pages were served with 200. Return {slug} so all pages prerender, exclude the root document (served by app/page.tsx), and set dynamicParams = false so unknown slugs are rejected at the router with a 404. The existing not-found.tsx page is unchanged. Amp-Thread-ID: https://ampcode.com/threads/T-01a07590-7d1a-72ec-826b-9081eed4f715 Co-authored-by: Amp --- src/app/[...slug]/page.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/app/[...slug]/page.tsx b/src/app/[...slug]/page.tsx index 96dd6900e..d12c71462 100644 --- a/src/app/[...slug]/page.tsx +++ b/src/app/[...slug]/page.tsx @@ -11,10 +11,17 @@ import {Suspense} from 'react'; export const maxDuration = 300; +// Every page is enumerated by generateStaticParams. Reject unknown slugs at the +// router so the site returns a real HTTP 404. Without this, notFound() runs +// inside the root layout's after the response has started streaming, +// and the not-found page is served with status 200. +export const dynamicParams = false; + export const generateStaticParams = async () => { - return allPosts.map(post => ({ - params: {slug: post._raw.flattenedPath.split('/')} - })); + return allPosts + // The root document is served by app/page.tsx, not this catch-all route. + .filter(post => post._raw.flattenedPath !== '') + .map(post => ({slug: post._raw.flattenedPath.split('/')})); }; export const generateMetadata = ({params}: Props) => { From 9c29b3940e8ebef54dd5257c0525f98405775d6e Mon Sep 17 00:00:00 2001 From: Marc LeBlanc <7050295+marcleblanc2@users.noreply.github.com> Date: Sun, 6 Sep 2026 03:37:29 -0600 Subject: [PATCH 2/2] chore: drop maxDuration from the doc page route The route is now fully prerendered, so it no longer runs as a serverless function and the timeout setting has no effect. Amp-Thread-ID: https://ampcode.com/threads/T-01a07590-7d1a-72ec-826b-9081eed4f715 Co-authored-by: Amp --- src/app/[...slug]/page.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/app/[...slug]/page.tsx b/src/app/[...slug]/page.tsx index d12c71462..4128dc0d5 100644 --- a/src/app/[...slug]/page.tsx +++ b/src/app/[...slug]/page.tsx @@ -9,8 +9,6 @@ import {getMDXComponent} from 'next-contentlayer/hooks'; import {notFound} from 'next/navigation'; import {Suspense} from 'react'; -export const maxDuration = 300; - // Every page is enumerated by generateStaticParams. Reject unknown slugs at the // router so the site returns a real HTTP 404. Without this, notFound() runs // inside the root layout's after the response has started streaming,