Mijan Richard
Website Vantage
← Back to postsThe Modern Way to Generate Sitemaps in Next.js (2025 Guide)

The Modern Way to Generate Sitemaps in Next.js (2025 Guide)

Published: 6/16/2025

Sitemaps are crucial for SEO, helping search engines discover and index your pages efficiently. With Next.js 13+, generating a sitemap has become easier than ever no more manual XML files or build scripts!

In this guide, I'll show you how to:
Automatically generate a sitemap (dynamic & always up-to-date)
Integrate with Sanity CMS (or any headless CMS)
Optimize for Vercel (edge caching, zero maintenance)

Why the Old Approach is Outdated

Traditionally, developers:

  1. Wrote a script to generate sitemap.xml
  2. Ran it during builds (npm run build)
  3. Committed the file to Git

Problems?

The Modern Solution: sitemap.js

Next.js 13+ introduced file-based sitemap generation. Instead of a static file, your sitemap is:
🔹 Generated on-demand when crawled
🔹 Always fresh (pulls latest CMS content)
🔹 Zero config (works out of the box)

Step-by-Step Implementation

1. Create app/sitemap.js

import { client } from "@/sanity/client";
import { getBaseUrl } from "@/lib/getBaseUrl";

export default async function sitemap() {
const baseUrl = getBaseUrl();

// 1. Static routes
const staticRoutes = [
{ url: "/", lastModified: new Date() },
{ url: "/blog", lastModified: new Date() },
];

// 2. Dynamic routes (from Sanity)
const posts = await client.fetch(` *[_type == "post"] { slug, _updatedAt } `);

const dynamicRoutes = posts.map((post) => ({
url: `${baseUrl}/blog/${post.slug.current}`,
lastModified: new Date(post._updatedAt),
}));

// 3. Combine all routes
return [...staticRoutes, ...dynamicRoutes];
}

The static routes points to the part of your websites that are relatively static - No frequent updates.

The dynamic routes points to the part of you websites that requires constant updates - individual blogs.

In my code, I have fetched all my post from sanity and I used the slug( similar to id) to create distinct urls for each blog.

2. Ensure getBaseUrl() Works in Production

// lib/getBaseUrl.ts
export function getBaseUrl() {
// Vercel auto-sets this
if (process.env.VERCEL_URL) {
return `https://${process.env.VERCEL_URL}`;
}

// Local dev fallback
return "http://localhost:3000";
}

3. Verify It Works

Visit:

https://yourdomain.com/sitemap.xml

If you see something like this , congratulations! you have successfully created your site map for your Next.js application

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://yourdomain.com</loc>
<lastmod>2024-02-20T00:00:00.000Z</lastmod>
</url>
<url>
<loc>https://yourdomain.com/blog</loc>
<lastmod>2024-02-20T00:00:00.000Z</lastmod>
</url>
<url>
<loc>https://yourdomain.com/blog/my-first-post</loc>
<lastmod>2024-02-15T00:00:00.000Z</lastmod>
</url>
</urlset>

Go ahead to your google search console(https://search.google.com/search-console/about) , submit your sitemap for verfication and hope that google indexes your page asap.

Why This is Better

🚀 Always Updated – No rebuilds needed when content changes
Fast – Vercel edge-caches responses
🔍 SEO-Friendly – GoogleBot gets fresh URLs instantly

Bonus: Add a robots.txt File

Create app/robots.js:

import { getBaseUrl } from "@/lib/getBaseUrl";

export default function robots() {
return {
rules: [
{ userAgent: "*", allow: "/" },
{ userAgent: "*", disallow: "/admin" },
],
sitemap: `${getBaseUrl()}/sitemap.xml`,
};
}

This auto-generates robots.txt pointing to your sitemap!

The generate robot.txt will look like this

User-agent: *
Allow: / # Lets bots crawl the entire site
Disallow: /admin # Blocks crawling of /admin

robots.txt gives google bot the permission to crawl certain parts of your website and denies them access to others.

Final Thoughts

Gone are the days of manual sitemap management. With Next.js dynamic sitemaps, you get:
Automatic updates (CMS changes reflect instantly)
No build scripts (zero maintenance)
Perfect SEO (Google loves fresh sitemaps)

Try it today! Your SEO rankings (and sanity) will thank you. 🚀

Want to see it in action? Check out my live sitemap at:
👉 https://richardwebsites.vercel.app/sitemap.xml

Found this helpful? Share it with other devs! 🚀


The Modern Way to Generate Sitemaps in Next.js (2025 Guide) | Website Vantage | Nigeria's Trusted Web Developer