By SitemapFixer Team
Updated April 2026

Next.js Sitemap: App Router and Pages Router Methods

Validate your Next.js sitemap freeCheck My Sitemap

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.

// app/sitemap.ts
import type { MetadataRoute } from 'next';
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://yoursite.com',
lastModified: new Date(),
changeFrequency: 'daily',
priority: 1,
}
{
url: 'https://yoursite.com/about',
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
}
];
}

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.

// next-sitemap.config.js
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: process.env.SITE_URL || 'https://yoursite.com',
generateRobotsTxt: true,
exclude: ['/admin/*','/api/*'],
}

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.

Check your Next.js sitemap is working
Free - validates every URL in 60 seconds
Analyze My Sitemap Free

Related Guides