Ship app/sitemap.ts and app/robots.ts

Next.js App Router turns app/sitemap.ts and app/robots.ts into /sitemap.xml and /robots.txt at build time. Return only canonical, indexable URLs from sitemap.ts with honest lastModified values, and set the rules plus the sitemap location from robots.ts. Both files must be reachable without authentication and must not be shadowed by static files in public/.

highIn codeimpact effort

Why this matters

Two file conventions give crawlers the map and the rules.

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 App Router project with a published-content data source
  • A single production site URL constant

How to apply it

  1. Create app/sitemap.ts

    Export a default function returning MetadataRoute.Sitemap. Map published records to { url, lastModified }, using absolute URLs from siteUrl and the record updated timestamp rather than the build time.

    Check: curl -s your production domain/sitemap.xml returns 200, is valid XML, and lists only canonical published URLs.

  2. Split large catalogs with generateSitemaps

    When the set exceeds 50,000 URLs or 50 MB, export generateSitemaps() returning ids and emit one file per id. Next.js then serves /sitemap/<id>.xml and an index at /sitemap.xml.

    Check: curl -s your production domain/sitemap.xml returns a sitemap index and every child loc returns 200.

  3. Add app/robots.ts

    Return rules with userAgent '*', allow '/' and disallow only paths with no search value. Set sitemap to siteUrl + '/sitemap.xml' and host to the production origin so one file documents the whole crawl policy.

    Check: curl -s your production domain/robots.txt returns 200, contains a Sitemap line and disallows no indexable path.

  4. Remove shadowing static files

    Delete public/robots.txt and public/sitemap.xml plus any proxy or edge rewrite for those paths. A static file or rewrite can serve instead of the metadata route and silently drop your changes.

    Check: curl -sI your production domain/robots.txt returns 200 with text/plain, and the repo has no public/robots.txt.

  5. Submit and monitor

    Submit the sitemap in Search Console and compare discovered URLs with indexed ones. Confirm robots.txt does not block CSS, JavaScript or any path that must rank.

    Check: The Search Console Sitemaps report lists the file as Success with a discovered URL count above zero.

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

Official references

Framework notes

nextjs-app

`app/sitemap.ts` and `app/robots.ts` export MetadataRoute objects; use `generateSitemaps()` above 50,000 URLs and delete `public/robots.txt`.

nextjs-pages

The Pages Router has no metadata routes; generate `/sitemap.xml` at build with `next-sitemap` (`next-sitemap` in a postbuild script) and keep `public/robots.txt` aligned.

Let your agent apply this + 161 more tips.

Pre-order — $19