Guides

How to Create an XML Sitemap in Next.js

Next.js supports a sitemap.ts file convention that generates a valid sitemap.xml automatically — this covers a static sitemap and one that includes dynamic routes pulled from your actual data.

Prerequisites

  • arrow_rightA Next.js App Router project (v13.3+)
  • arrow_rightA function that returns your dynamic route data (e.g. all blog post slugs)

Step 1: Create the Sitemap File

app/sitemap.ts

import type { MetadataRoute } from 'next';

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    { url: 'https://example.com', lastModified: new Date(), priority: 1 },
    { url: 'https://example.com/about', lastModified: new Date(), priority: 0.8 },
  ];
}

Step 2: Add Dynamic Routes

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await getAllPosts();
  const postEntries = posts.map((post) => ({
    url: `https://example.com/blog/${post.slug}`,
    lastModified: post.updatedAt,
  }));
  return [{ url: 'https://example.com' }, ...postEntries];
}

Common Errors

  • arrow_rightSitemap includes noindex or redirected pages — filter your data source to only genuinely indexable URLs before mapping them into the sitemap
  • arrow_rightlastModified showing the current date on every build — pull the actual content update timestamp from your data source rather than using new Date() at build time
  • arrow_rightSitemap exceeds 50,000 URLs — split into multiple sitemap files referenced by a sitemap index

Best Practices

  • arrow_rightGenerate the sitemap from the same data source that powers your routes, so they can't drift out of sync
  • arrow_rightUse real lastModified dates tied to actual content changes
  • arrow_rightSubmit the sitemap URL in Google Search Console after significant changes

Frequently Asked Questions

Does Next.js generate robots.txt too?add

Yes, via the same file-convention pattern — an app/robots.ts file can export the rules, and Next.js serves it at /robots.txt automatically.

How do I handle a very large number of URLs?add

Return an array of sitemaps from a generateSitemaps function, splitting URLs across multiple sitemap files under the 50,000 URL / 50MB limit per file.

Do I need to resubmit the sitemap after every change?add

Not strictly — search engines periodically recrawl a submitted sitemap, but resubmitting in Search Console after major changes can prompt a faster recrawl.

BUILDING SOMETHING SIMILAR?

If you'd rather have this built and shipped than build it yourself, I'm available for freelance and contract work.