Next.js Sitemap: App Router and Pages Router Methods
Next.js does not generate a sitemap automatically. You need to add one yourself. The method depends on which router you are using. The App Router (Next.js 13.2+) has a built-in sitemap convention. The Pages Router requires either a manual setup or the next-sitemap package.
App Router: Built-in sitemap.ts (Recommended)
In the App Router, create a file at app/sitemap.ts. Next.js automatically serves its output at /sitemap.xml. This is the cleanest approach with no extra dependencies.
For dynamic routes - like blog posts fetched from a database - fetch your data inside the sitemap function and map the results to URL entries. The sitemap function can be async, so you can use fetch or query your database directly.
Pages Router: next-sitemap Package
Install with: npm install next-sitemap. Then create a next-sitemap.config.js at your project root.
Add "postbuild": "next-sitemap" to your package.json scripts. This generates sitemap.xml and robots.txt in your public folder after every build. The sitemap is then served as a static file.
Common Next.js Sitemap Problems
Dynamic routes missing from sitemap
Static pages (about, contact) are easy to add manually. Dynamic routes like blog posts at /blog/[slug] require you to fetch all slugs at build time and generate a URL entry for each. In the App Router, call your database or CMS API inside the sitemap function. In next-sitemap, use the additionalPaths option or a custom transform function.
Sitemap showing localhost URLs
If your sitemap contains http://localhost:3000 URLs, your NEXT_PUBLIC_SITE_URL or siteUrl config is missing or wrong. Set an environment variable in your deployment (SITE_URL=https://yoursite.com) and make sure your sitemap function uses that variable as the base URL. On Vercel, add SITE_URL to your project environment variables.
Sitemap not updating after new content
In the App Router, the sitemap function runs at request time by default but can be cached. If new content is not appearing, check your revalidation settings. Add export const revalidate = 3600 to your sitemap.ts to revalidate every hour. For next-sitemap with the Pages Router, the sitemap is regenerated on every build - you need to trigger a new build to update it.
Related Guides
- WordPress Sitemap: Setup, Fix, and Submit Guide
- Shopify Sitemap: Location, Errors, and How to Submit It
- Wix Sitemap: How It Works and How to Submit It
- Squarespace Sitemap: How It Works and Common Fixes
- Webflow Sitemap: How It Works and How to Submit It
- Django Sitemap: Using the Built-in Sitemaps Framework
- SvelteKit Sitemap: Generate Dynamic XML Sitemaps
- Remix Sitemap: Generate XML Sitemaps in Remix Apps
- 7 Next.js Sitemap Mistakes That Break Google Indexing