How to generate sitemap paths in NextJS with Sanity dynamic routes?

9 replies
Last updated: Nov 29, 2025
Anyone know how to create a sitemap when using NextJS with Sanity?
Not a Sanity specific question I know

I found this from Lee Rob
https://leerob.io/blog/nextjs-sitemap-robots
It doesn't generate the paths though just the file name so,
<https://mysite.com/folder/[file]>
AI Update

You're on the right track! The article you found from Lee Robinson shows how to create the sitemap file, but you need to populate it with actual paths from your Sanity content. Here's how to create a dynamic sitemap with Next.js and Sanity:

Generate Dynamic Paths from Sanity

First, create a GROQ query to fetch all your documents that should appear in the sitemap. Add this to your queries.ts file:

export const SITEMAP_QUERY = defineQuery(`
  *[_type in ["page", "post"] && defined(slug.current)] {
    "href": select(
      _type == "page" => "/" + slug.current,
      _type == "post" => "/posts/" + slug.current,
      slug.current
    ),
    _updatedAt
  }
`)

This query dynamically builds the full path for each document type and includes the last updated date.

Create the Sitemap Route

Next.js App Router has a special sitemap.ts route convention that returns a MetadataRoute.Sitemap type. Create app/sitemap.ts:

import { MetadataRoute } from "next";
import { client } from "@/sanity/lib/client";
import { SITEMAP_QUERY } from "@/sanity/lib/queries";

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  try {
    const paths = await client.fetch(SITEMAP_QUERY);

    if (!paths) return [];

    const baseUrl = process.env.VERCEL
      ? `https://${process.env.VERCEL_URL}`
      : "http://localhost:3000";

    return paths.map((path) => ({
      url: new URL(path.href!, baseUrl).toString(),
      lastModified: new Date(path._updatedAt),
      changeFrequency: "weekly",
      priority: 1,
    }));
  } catch (error) {
    console.error("Failed to generate sitemap:", error);
    return [];
  }
}

Generate TypeScript Types

Since you created a new query, regenerate your types:

npm run typegen

Test Your Sitemap

Visit http://localhost:3000/sitemap.xml to see your dynamically generated sitemap. You should see properly formatted XML with all your Sanity content paths:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://mysite.com/about</loc>
    <lastmod>2025-01-10T14:13:34.000Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1</priority>
  </url>
  <!-- more URLs... -->
</urlset>

The beauty of this approach is that your sitemap automatically updates whenever you publish content in Sanity, and you can customize the changeFrequency and priority values based on your content types.

For more details on SEO optimization with Sanity and Next.js, check out the SEO optimized content with Next.js course.

Show original thread
9 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?