
Your sitemap works. Google sees it. But your pages still don’t index. Here’s why.
Your site is live, sitemap is generated… yet Google is NOT indexing your pages properly.
This is more common than you think. The issue is usually not your content - it's your sitemap architecture.
In this guide, you'll learn how to properly build a Next.js sitemap system that works in real production environments.
Real Problem:
In our production project:
- Sitemap was valid
- URLs were correct
- Google could fetch it
Yet in Google Search Console:
- Pages showed “Discovered – currently not indexed”
- Some URLs were never crawled
What We Found
The issue wasn’t visibility — it was crawl efficiency.
- Too many URLs in a single sitemap
- No clear segmentation (products, static, etc.)
- No pagination strategy
This made it harder for Google to prioritize crawling.
Common Developer Mistake
Many developers:
- Generate a sitemap
- Check it in the browser
- Submit it to Google Search Console
And assume everything is done. But pages still don’t get indexed properly.
Why?
- Poor sitemap structure
- No scalability planning
- Ignoring search engine limitations
Static vs Dynamic Sitemap
Static Sitemap (Simple Websites)
If your site has fixed pages like:
- Home
- About
- Contact
You can create a static sitemap manually.
Example:
// src/app/static/sitemap.ts
import { MetadataRoute } from 'next';
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://example.com',
lastModified: new Date(),
},
{
url: 'https://example.com/about',
lastModified: new Date(),
},
];
}Dynamic Sitemap (Real-World Use Case)
For dynamic content like:
- Blog posts
- Products
- Categories
You need to fetch data and generate URLs dynamically.
Example:
// src/app/blog/sitemap.ts
import { MetadataRoute } from 'next';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
return posts.map((post: any) => ({
url: `https://example.com/blog/${post.slug}`,
lastModified: new Date(post.updatedAt),
}));
}
The Real Problem in Production
Everything works fine locally. But in production:
- Sitemap loads correctly
- Yet Google fails to index pages
Root Causes:
1. Sitemap Limits
- Search engines have strict limits:
- Maximum 50,000 URLs per sitemap
- Maximum 50MB file size
2. Large-Scale Websites
- E-commerce sites with thousands of products
- Blogs with hundreds of posts
A single sitemap is not enough.
The Solution: Sitemap Index Architecture
To handle scalability, you need a Sitemap Index that references multiple child sitemaps.
App Structure
src/app/
│
├── sitemap.xml/route.ts
├── static/sitemap.ts
├── product/sitemap.ts 1. Create Sitemap Index
import { NextResponse } from "next/server";
import { getProductCount } from "@/lib/api";
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL!;
const PRODUCT_PER_SITEMAP = 1000;
export async function GET() {
const totalProduct = await getProductCount();
const totalProductSitemaps = Math.max(
1,
Math.ceil(totalProduct / PRODUCT_PER_SITEMAP)
);
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>${SITE_URL}/static/sitemap.xml</loc>
</sitemap>
${Array.from({ length: totalProductSitemaps }, (_, i) => {
return `
<sitemap>
<loc>${SITE_URL}/product/sitemap/${i + 1}.xml</loc>
</sitemap>`;
}).join("")}
</sitemapindex>`;
return new NextResponse(xml, {
headers: {
"Content-Type": "application/xml; charset=utf-8",
"Cache-Control": "s-maxage=3600, stale-while-revalidate=86400",
},
});
}2. Static Sitemap
import type { MetadataRoute } from "next";
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL!;
export default function sitemap(): MetadataRoute.Sitemap {
const now = new Date();
return [
{
url: `${SITE_URL}/`,
lastModified: now,
changeFrequency: "daily",
priority: 1,
},
{
url: `${SITE_URL}/about-us`,
lastModified: now,
changeFrequency: "monthly",
priority: 0.7,
},
];
}
3. Dynamic Paginated Sitemap
import type { MetadataRoute } from "next";
import { getProducts, getProductsCount } from "@/lib/api";
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL!;
const PRODUCT_PER_SITEMAP = 1000;
type Product = {
slug: string;
updatedAt?: string;
publishedAt?: string;
};
export async function generateSitemaps() {
const totalProducts = await getProductsCount();
const totalSitemaps = Math.max(
1,
Math.ceil(totalProducts / PRODUCT_PER_SITEMAP)
);
return Array.from({ length: totalSitemaps }, (_, i) => ({
id: i + 1,
}));
}
export default async function sitemap({
id,
}: {
id: Promise<number>;
}): Promise<MetadataRoute.Sitemap> {
const products = await getProducts(id, PRODUCT_PER_SITEMAP);
return products.map((product: Product) => ({
url: `${SITE_URL}/product/${product.slug}`,
lastModified:
product.updatedAt || product.publishedAt || new Date().toISOString(),
changeFrequency: "weekly",
priority: 0.8,
}));
}How Auto Scaling Works
/product/1.xml → contains first batch
/product/2.xml → next batchAnd continues automatically using pagination. This ensures:
- No sitemap exceeds limits
- Efficient indexing
Debug Checklist
If your sitemap is not indexing:
- Sitemap returns 200 OK
- Correct application/xml header
- No blocking in robots.txt
- Submitted in Google Search Console
- Each sitemap < 50k URLs
- Response time < 2 seconds
- URLs are crawlable (no noindex)
Important
- Don’t wait for 50k URLs → split at 5k–10k
- Always include lastModified
- Cache sitemap response if possible
- Avoid heavy DB/API calls inside sitemap
- Use ISR or edge caching for performance
Next.js gives you powerful SEO tools. But without proper sitemap architecture, your content may never reach its full potential.
Read more

10 Powerful Chrome Extensions for SEO in 2026 - Tools Every Marketer and Developer Should Know
Discover the best Chrome extensions for SEO analysis, keyword research, and technical website audits. These powerful tools help marketers, bloggers, and developers quickly analyze pages, track rankings, and uncover SEO opportunities directly from the browser.

What Is a Modern Developer Stack in 2026?: A Practical Guide to Building Real Production Systems
Many tutorials teach modern web stacks through simple demo projects, but real production systems require deeper understanding. This guide explains the practical skills developers need to build secure, scalable applications using Next.js, APIs, authentication, databases, and modern web architecture.

From Zero to Production: A Real-World Guide to Building and Deploying a Production-Grade Next.js Website
Many developers build beautiful Next.js projects but struggle to take them to a true production environment. This guide explains a practical architecture covering frontend, backend, database, file storage, and deployment used in real-world applications.
