Dynamic Sitemap Generation for Next.js with Sanity Pages

4 replies
Last updated: Nov 29, 2025
Not so much a "getting started" question, but I am curious how others are handling a sitemap for their Next.js application with dynamic pages from Sanity. I am currently using
next-sitemap
but to pick any new pages up a new release of my app would have to be released. However, there is this snippet from
next-sitemap
for creating dynamic/server-side sitemaps... I just feel it is weird to have 2 sitemaps with duplicate content is just _odd_/wrong.
AI Update

You're right to feel that having two sitemaps with duplicate content is odd! The good news is that with modern Next.js (especially App Router), you don't actually need next-sitemap at all anymore. You can create a fully dynamic, server-side sitemap using Next.js's built-in MetadataRoute.Sitemap API.

The Modern Approach: Single Dynamic Sitemap

Instead of using next-sitemap, create a app/sitemap.ts (or app/sitemap.xml/route.ts) file that queries Sanity directly at request time. This gives you a single sitemap that's always up-to-date without needing redeployments:

// app/sitemap.ts
import { MetadataRoute } from 'next'
import { sanityFetch } from '@/sanity/lib/client'

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const query = `*[_type in ["page", "post"] && defined(slug.current)] {
    "href": select(
      _type == "page" => "/" + slug.current,
      _type == "post" => "/posts/" + slug.current
    ),
    _updatedAt
  }`
  
  const pages = await sanityFetch({ query })
  
  return pages.map((page) => ({
    url: `https://yourdomain.com${page.href}`,
    lastModified: new Date(page._updatedAt),
    changeFrequency: 'weekly',
    priority: 0.8,
  }))
}

This approach is covered in detail in Sanity's dynamic sitemap guide.

Why This is Better

  1. No duplicate content - Single source of truth
  2. Always current - Reflects content changes immediately without redeployment
  3. Native Next.js - No extra dependencies
  4. Proper caching - Next.js handles revalidation automatically
  5. Uses Sanity's _updatedAt - Accurate lastModified dates for search engines

When You Might Still Use next-sitemap

The only real reason to keep next-sitemap is if you need its postbuild generation for static exports or have complex sitemap index splitting requirements. But for most Sanity + Next.js apps with dynamic content, the native Next.js approach is simpler and more reliable.

The "two sitemaps" pattern from next-sitemap's docs (using getServerSideSitemap in a server-side route like app/server-sitemap.xml/route.ts) was really a workaround before Next.js had first-class sitemap support. Now that Next.js has MetadataRoute.Sitemap in the App Router, you can do everything in one place without the awkwardness of merging static and dynamic sitemaps or dealing with duplicate entries.

Show original thread
4 replies

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?