---
title: "Ship app/sitemap.ts and app/robots.ts"
description: "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/."
url: "https://seo-mcp.io/t/ship-app-sitemap-ts-and-app-robots-ts"
---

# 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/.

## Prerequisites

- Next.js App Router project with a published-content data source
- A single production site URL constant

## Steps

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.

## Source

@seo-mcp on 2026-10-19: https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap

Canonical: https://seo-mcp.io/t/ship-app-sitemap-ts-and-app-robots-ts
