Return true 404s with notFound()

A route that renders an empty template with status 200 is a soft 404: crawlers index it and users see nothing. Call notFound() when a record is missing or the slug is invalid, add app/not-found.tsx for the layout, and confirm the response status over HTTP. Keep redirects for moved content and reserve notFound() for genuinely absent pages.

mediumIn codeimpact effort

Why this matters

Call notFound() instead of rendering an empty page with status 200.

Get the full breakdown

The extended brief explains when this works, when it does not, and the trade-offs. Join the waitlist and it unlocks for every tip when sign-in opens; MCP access is the paid part.

Join the waitlist

Before you start

  • Next.js project with dynamic routes that can receive unknown ids
  • A not-found page that matches the site layout

How to apply it

  1. Find the soft-404 routes

    Look for dynamic routes that render a shell when the record query returns nothing, and check the HTTP status of a deliberately invalid slug.

    Check: curl -sI your production domain/<dynamic-route>/does-not-exist returns 200 before the fix.

  2. Call notFound() on missing data

    Import notFound from next/navigation and call it when the record is absent or invalid, before rendering any content.

    Check: The same invalid slug now returns 404 after rebuilding.

  3. Add or fix app/not-found.tsx

    Create a not-found page with a short explanation, a link home and navigation, and no indexable content that competes with real pages.

    Check: The 404 response renders the not-found layout with a link home.

  4. Keep redirects for moved content

    Move slugs that changed to redirect rules and leave notFound() for genuinely absent records. Re-check Search Console for soft 404 reports after deploy.

    Check: A moved slug redirects to its new URL, while an unknown slug returns 404.

Get the prompt for your agent

A ready-to-paste prompt for your agent that implements this tip and verifies the result in your repo.

Join the waitlist

Source: seo-mcp playbook · curated entry · report an error

Framework notes

nextjs-app

Call `notFound()` from `page.tsx` when data is missing and add `app/not-found.tsx`; Next.js renders it with a real 404 status.

nextjs-pages

Return `{ notFound: true }` from `getServerSideProps` or `getStaticProps` and keep `pages/404.tsx` as the fallback layout.

Official references

Let your agent apply this + 161 more tips.

Pre-order — $19