This one's a genuinely reasonable setting that causes a genuinely confusing symptom, a brand new piece of content, added correctly, visible in your CMS, just returns a 404 on the live site, with nothing in your code actually wrong.
What dynamicParams Actually Controls
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map((post) => ({ slug: post.slug }));
}
export const dynamicParams = false; // reject anything not in the list above
export default async function BlogPost({ params }) {
const { slug } = await params;
const post = await getPost(slug);
if (!post) notFound();
return <article>{post.content}</article>;
}
generateStaticParams runs at build time, pre-rendering a page for every slug it returns. dynamicParams controls what happens for a slug that shows up in a request but wasn't in that build-time list. The default is true, meaning Next.js will attempt to render that path on demand anyway, genuinely useful behavior for content added after the last build. Setting it explicitly to false tells Next.js to immediately 404 anything not in the pre-generated list, full stop, no attempt to render it fresh.
Why Someone Sets This Deliberately
dynamicParams = false is a reasonable, intentional choice in specific situations, guaranteeing that only explicitly known, build-time-verified paths are ever servable, useful for something like a fixed set of product pages where an unexpected slug showing up would genuinely indicate a bug or a malicious request, not legitimate new content. It's not a mistake in that context, it's a deliberate constraint.
Where This Actually Causes Real Problems
For content that genuinely grows over time, a blog, a CMS-driven catalog, anything where new items get added independently of a code deployment, this exact setting means every new item is completely inaccessible, a real 404, until the next build actually happens and includes it in generateStaticParams's output.
1. Blog post published in the CMS at 2:00 PM
2. Someone shares the link
3. Visitor clicks it, gets a 404
4. The post is completely correct in the CMS, the slug is right, everything's fine there
5. The site just has no idea this post exists yet, since the last build predates it
This is exactly the kind of gap that's genuinely confusing to diagnose, since checking the CMS shows everything looks correct, checking the code shows the query logic is fine, and the actual cause, a build-time snapshot that's now stale, doesn't announce itself anywhere obvious.
The Actual Fix, Depending on What You Actually Need
If new content should be servable immediately without waiting for a rebuild, this is almost always the right default, just don't set dynamicParams to false at all, or set it explicitly to true:
export const dynamicParams = true; // or simply omit this line, true is the default
New slugs not in the build-time list get rendered on demand, then, depending on your caching setup, can be cached going forward, giving you both immediate availability and good performance after the first request.
If you genuinely need the strict guarantee dynamicParams = false provides, a fixed, known set of pages where anything else really should 404, pair it with a deliberate process for triggering a new build whenever new content is actually added, a webhook from your CMS triggering a redeploy, rather than relying on a periodic or manual build schedule that leaves a real gap between content going live and the site actually knowing about it.
// A CMS webhook triggering an on-demand revalidation or rebuild
// whenever new content is actually published, closing the gap
Why This Interacts Badly With Good SEO Practices
This is a genuinely important compounding issue. If you've set up automatic sitemap generation, covered in an earlier post, and someone shares a freshly published post before the next build happens, both the visitor clicking the link and, worse, a search engine crawler attempting to index that URL early, encounter a real 404. A crawler hitting a 404 on a URL is a real, negative signal, not a neutral non-event, and repeated early 404s on genuinely valid content can meaningfully hurt how quickly and how well that content ends up indexed once it is actually available.
How to Check If This Is Affecting You
If you're using dynamicParams = false anywhere, specifically check how long the gap actually is between content being published in your CMS and the next site build or deploy happening. If that gap is measured in hours or days rather than minutes, and the content in question is meant to be immediately live, that gap is a real, live problem, not a theoretical edge case.
grep -rn "dynamicParams" --include="*.tsx" app/
The Actual Rule
dynamicParams = false is a deliberate access-control decision, not a performance optimization, and it should only be used where truly unexpected paths genuinely should be rejected. For any content source that grows independently of your deployment schedule, a blog, a CMS-driven catalog, user-generated content, the default true behavior, or an explicit true, is almost always what you actually want, letting new content render on demand rather than waiting on the next build to even acknowledge it exists.
If you're using dynamicParams = false anywhere in a project with content that grows outside your deploy cycle, worth checking today whether new content is actually reachable the moment it's published, or silently 404ing until the next deploy catches up. Drop what you find in the comments.
Get the templates: https://pixelanas.gumroad.com
Anas, full-stack Next.js developer building SaaS products and premium templates. X: @ASheikh69751
Top comments (0)