Skip to content

Rule · SEO

Missing page returns HTTP 200 (soft 404)

seo/soft-404errorvoid seoupdated

Why it matters

Unknown URLs that answer 200 get crawled and indexed as thin duplicates, and AI crawlers already waste about a third of fetches on 404s. In Next.js 16, notFound() inside a Suspense boundary streams a 200 with noindex.

How to fix it

Return 404/410 for unknown URLs. In Next.js, resolve existence at the top of page.tsx or in generateMetadata (before any <Suspense>), or set dynamicParams = false for prerendered slugs.

Example

tsx
// app/blog/[slug]/page.tsx
export const dynamicParams = false // unknown slugs → real 404

export default async function Post({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params
  const post = await getPost(slug)
  if (!post) notFound() // before any <Suspense>, so the status is still 404
  return <Article post={post} />
}

References

void seo reports 60 rules in this category. What search engines need from the raw response: status codes, titles and descriptions in <head>, self-referencing canonicals, one h1, crawlable links, Open Graph, icons, robots.txt and a sitemap with real dates.