Next.js XML Sitemap Validator & Dynamic sitemap.ts Generator

Validate dynamic Next.js App Router sitemap.ts files, debug 50k URL thresholds, and generate type-safe MetadataRoute.Sitemap TypeScript handlers.

Advertisement
AdSense Placeholder: Top Leaderboard Ad (728x90 / 320x50)

Displayed below main page header or above the tool container. • Zero CLS Container

Resolve Google Search Console Crawl & Indexing Issues for Next.js

Audit crawler permissions, verify canonical tags, and troubleshoot indexation drops.

10 URLs

Paste absolute URLs (up to 200+). Protocol will be upgraded to HTTPS automatically if enabled.

Global Sitemap Directives & Defaults

0.8
0.1 (Low)1.0 (Critical)
import { MetadataRoute } from 'next';

export default function sitemap(): MetadataRoute.Sitemap {
  return [
  {
    url: 'https://yourdomain.com/',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'daily',
    priority: 1,
  },
  {
    url: 'https://yourdomain.com/tools',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.8,
  },
  {
    url: 'https://yourdomain.com/tools/xml-sitemap-generator',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.7,
  },
  {
    url: 'https://yourdomain.com/tools/robots-txt-generator-validator',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.7,
  },
  {
    url: 'https://yourdomain.com/tools/canonical-redirect-auditor',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.7,
  },
  {
    url: 'https://yourdomain.com/blog',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.8,
  },
  {
    url: 'https://yourdomain.com/blog/nextjs-dynamic-sitemap-guide',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.7,
  },
  {
    url: 'https://yourdomain.com/recipes/how-to-fix-discovered-currently-not-indexed',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.7,
  },
  {
    url: 'https://yourdomain.com/about',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.8,
  },
  {
    url: 'https://yourdomain.com/contact',
    lastModified: new Date('2026-10-12'),
    changeFrequency: 'weekly',
    priority: 0.8,
  }
  ];
}
Total URLs
10
Payload Size
1.81 KB
Google 50,000 URL Limit10 / 50,000
100% Client-Side PrivateSitemaps.org 0.9
Advertisement
AdSense Placeholder: Native In-Feed Ad (Responsive)

Separates the interactive tool output from the deep technical guide. • Zero CLS Container

Direct Answer: Next.js App Router (sitemap.ts / Route Handlers) Sitemap Architecture & Failure Modes

Next.js App Router (Next.js 13.3+, Next.js 14, and Next.js 15+) provides a built-in file-based convention for programmatic sitemaps via `app/sitemap.ts`. Exporting a default function returning `MetadataRoute.Sitemap` automatically builds a compliant XML sitemap with valid `application/xml` MIME headers, incremental static regeneration (ISR), and runtime edge caching. Common Google Search Console validation failures occur when developers author custom Route Handlers (`app/sitemap.xml/route.ts`) that return `text/html` instead of `application/xml`, when unescaped query string ampersands break XML parsers, or when dynamic catalogs exceed 50,000 URLs without using Next.js `generateSitemaps()` for automated sitemap index chunking.

Generating Dynamic, Edge-Cached sitemap.ts in Next.js App Router

Technical deep dive into Next.js App Router (sitemap.ts / Route Handlers) sitemap quirks, sub-sitemap splitting, and crawl waste elimination

Modern Next.js applications require programmatic sitemap generation to handle dynamic database routes, multi-locale subpaths, and headless CMS webhooks without manual file maintenance.

1. The Native app/sitemap.ts Convention

Instead of manually creating XML strings, Next.js provides the MetadataRoute.Sitemap TypeScript interface in app/sitemap.ts (or src/app/sitemap.ts):

// app/sitemap.ts (Next.js App Router)
import { MetadataRoute } from 'next';

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await fetch('https://api.example.com/posts').then(res => res.json());

  return posts.map((post: any) => ({
    url: `https://example.com/blog/${post.slug}`,
    lastModified: new Date(post.updatedAt),
    changeFrequency: 'weekly',
    priority: 0.8,
  }));
}

2. Scaling Past 50,000 URLs with generateSitemaps()

If your application has more than 50,000 dynamic URLs (e.g. large programmatic SEO directories or e-commerce stores), Next.js App Router supports automated sitemap index partitioning using the generateSitemaps() export:

// app/sitemap.ts (Automated Sitemap Index Partitioning)
import { MetadataRoute } from 'next';

export async function generateSitemaps() {
  // Return array of sitemap IDs based on database count
  return [{ id: 0 }, { id: 1 }, { id: 2 }];
}

export default async function sitemap({ id }: { id: number }): Promise<MetadataRoute.Sitemap> {
  const limit = 50000;
  const start = id * limit;
  const items = await getItemsFromDb(start, limit);

  return items.map((item) => ({
    url: `https://example.com/product/${item.slug}`,
    lastModified: new Date(item.updatedAt),
  }));
}

Next.js automatically exposes a parent sitemap index at /sitemap.xml referencing /sitemap/0.xml, /sitemap/1.xml, and /sitemap/2.xml.

3. Edge Caching & Revalidation

To prevent heavy database queries on every crawler hit, export export const revalidate = 86400; (24 hours) at the top of app/sitemap.ts. Next.js will cache the compiled XML response at the Vercel/Cloudflare edge, serving it instantly with zero server execution delay.

app/sitemap.ts (TypeScript Example)Next.js 14/15 App Router
// app/sitemap.ts (Next.js App Router with Dynamic generateSitemaps Partitioning)
import { MetadataRoute } from 'next';

const BASE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://yourdomain.com';

export const revalidate = 86400; // Cache XML at the edge for 24 hours

export async function generateSitemaps() {
  // Divide total catalog into chunks of 50,000 URLs
  return [{ id: 0 }, { id: 1 }];
}

export default async function sitemap({
  id,
}: {
  id: number;
}): Promise<MetadataRoute.Sitemap> {
  const limit = 50000;
  const start = id * limit;
  const dynamicPosts = await fetchPostsFromDatabase(start, limit);

  const entries = dynamicPosts.map((post) => ({
    url: `${BASE_URL}/blog/${post.slug}`,
    lastModified: new Date(post.updatedAt),
    changeFrequency: 'weekly' as const,
    priority: 0.8,
  }));

  if (id === 0) {
    return [
      {
        url: BASE_URL,
        lastModified: new Date(),
        changeFrequency: 'daily',
        priority: 1.0,
      },
      ...entries,
    ];
  }

  return entries;
}

How to Configure & Validate Next.js Sitemaps (Step-by-Step)

Five proven engineering steps to deploy error-free XML sitemaps in Next.js App Router (sitemap.ts / Route Handlers)

  1. 1

    Create app/sitemap.ts in App Router

    Add a new file at `src/app/sitemap.ts` or `app/sitemap.ts` in your Next.js project.

  2. 2

    Import MetadataRoute and Type Return

    Import `import { MetadataRoute } from 'next';` and ensure your default async export returns `Promise<MetadataRoute.Sitemap>`.

  3. 3

    Fetch Dynamic Slugs from Database or CMS

    Fetch your published posts, products, or programmatic items, formatting ISO `Date` instances for `lastModified`.

  4. 4

    Configure generateSitemaps() for >50k Datasets

    If your catalog exceeds 50,000 entries, export `generateSitemaps()` alongside `sitemap({ id })` to generate automated sub-sitemaps.

  5. 5

    Set Edge Revalidation and Validate in OmniSEO

    Export `export const revalidate = 86400;` to enable edge caching, then paste your live XML endpoint into our validator to confirm compliant serialization.

Next.js XML Sitemap FAQ

Troubleshooting Google Search Console validation errors, 50k limits, and platform configuration

How do I handle more than 50,000 URLs in Next.js App Router sitemap.ts?

In Next.js App Router, export an asynchronous `generateSitemaps()` function in `app/sitemap.ts` that returns an array of sitemap ID objects (e.g., `return [{ id: 0 }, { id: 1 }];`). Then update your default sitemap function to accept `{ id }: { id: number }` as props to paginate data fetching. Next.js will automatically build a sitemap index at `/sitemap.xml` pointing to `/sitemap/0.xml` and `/sitemap/1.xml`.

Why does my custom Next.js Route Handler sitemap fail Google Search Console validation?

If building a custom Route Handler (`app/sitemap.xml/route.ts`), you must return a `Response` object with the header `'Content-Type': 'application/xml; charset=utf-8'`. Returning plain text or `text/html` causes Google Search Console to reject the sitemap with a MIME type mismatch error.

How do I set dynamic cache headers or ISR revalidation on Next.js sitemaps?

Export `export const revalidate = 86400;` (time in seconds) or `export const dynamic = 'force-dynamic'` directly inside `app/sitemap.ts`. This controls how Vercel and Next.js cache and revalidate your XML sitemap at the network edge.

CMS & Framework XML Sitemap Generators

Switch presets to inspect, debug, and generate XML sitemaps for your specific tech stack

Looking for generic XML sitemap generation? Use the Universal XML Sitemap Generator & Validator.

Related Tools & Next Workflow Steps

Complementary utilities to streamline your SEO audit, indexing, and content strategy.

Browse All 35 Utilities
New

Robots.txt Generator & Validator

Generate, test, and validate standard-compliant robots.txt files with live syntax checking, multi-user-agent rules, and sitemap directives.

technicalOpen
New

Redirect Rule & Regex Mapper

Generate, test, and export 301 and 302 redirect rules for Next.js, Nginx, Apache, and Cloudflare with real-time regex path testing.

technicalOpen
New

Bulk Canonical Normalizer & Auditor

Audit raw URLs in bulk, strip tracking parameters (UTMs/gclid), enforce trailing slash rules, and detect duplicate content risks.

technicalOpen
Updated

Canonical URL Builder

Build self-referential and cross-domain canonical link tags to unify Google ranking signals and prevent duplicate content penalties.

technicalOpen
Advertisement
AdSense Placeholder: Top Leaderboard Ad (728x90 / 320x50)

Displayed below main page header or above the tool container. • Zero CLS Container