Skip to main content
CodeRocket
SEOhightechnical

Create and submit an XML sitemap

rule · sitemap

XML sitemaps help search engines discover and index all your pages.

Code Example

XML
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2024-01-15</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://example.com/about</loc>
    <lastmod>2024-01-10</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
</urlset>

Why It Matters

Search engines may not discover all your pages through links alone—a sitemap ensures every important page gets indexed, especially for large or newly launched sites.

Sitemap Elements

ElementPurposeRequired
locFull URL of the pageYes
lastmodLast modification dateRecommended
changefreqUpdate frequency hintOptional
priorityRelative importance (0.0-1.0)Optional

Next.js Dynamic Sitemap

TypeScript
// app/sitemap.ts
import { MetadataRoute } from 'next'
 
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const baseUrl = 'https://example.com'
 
  // Static pages
  const staticPages = [
    '',
    '/about',
    '/contact',
    '/pricing',
  ].map(route => ({
    url: `${baseUrl}${route}`,
    lastModified: new Date(),
    changeFrequency: 'monthly' as const,
    priority: route === '' ? 1.0 : 0.8,
  }))
 
  // Dynamic pages from database
  const products = await getProducts()
  const productPages = products.map(product => ({
    url: `${baseUrl}/products/${product.slug}`,
    lastModified: product.updatedAt,
    changeFrequency: 'weekly' as const,
    priority: 0.7,
  }))
 
  // Blog posts
  const posts = await getPosts()
  const blogPages = posts.map(post => ({
    url: `${baseUrl}/blog/${post.slug}`,
    lastModified: post.updatedAt,
    changeFrequency: 'monthly' as const,
    priority: 0.6,
  }))
 
  return [...staticPages, ...productPages, ...blogPages]
}

Large Sites: Sitemap Index

XML
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://example.com/sitemap-pages.xml</loc>
    <lastmod>2024-01-15</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://example.com/sitemap-products.xml</loc>
    <lastmod>2024-01-14</lastmod>
  </sitemap>
  <sitemap>
    <loc>https://example.com/sitemap-blog.xml</loc>
    <lastmod>2024-01-13</lastmod>
  </sitemap>
</sitemapindex>
TypeScript
// app/sitemap.ts - Multiple sitemaps
import { MetadataRoute } from 'next'
 
export async function generateSitemaps() {
  const productCount = await getProductCount()
  const numSitemaps = Math.ceil(productCount / 50000)
 
  return Array.from({ length: numSitemaps }, (_, i) => ({ id: i }))
}
 
export default async function sitemap({
  id,
}: {
  id: number
}): Promise<MetadataRoute.Sitemap> {
  const start = id * 50000
  const products = await getProducts({ start, limit: 50000 })
 
  return products.map(product => ({
    url: `https://example.com/products/${product.slug}`,
    lastModified: product.updatedAt,
  }))
}

Priority Guidelines

Page TypeSuggested Priority
Homepage1.0
Main category pages0.8-0.9
Product/service pages0.7-0.8
Blog posts0.5-0.7
Legal pages0.3-0.5
Archive/tag pages0.3-0.4

Reference in robots.txt

TEXT
User-agent: *
Allow: /
 
Sitemap: https://example.com/sitemap.xml

Image Sitemap Extension

XML
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
  <url>
    <loc>https://example.com/products/widget</loc>
    <image:image>
      <image:loc>https://example.com/images/widget.jpg</image:loc>
      <image:title>Widget Product Photo</image:title>
    </image:image>
    <image:image>
      <image:loc>https://example.com/images/widget-side.jpg</image:loc>
      <image:title>Widget Side View</image:title>
    </image:image>
  </url>
</urlset>

Submit to Search Engines

Shell
# Google Search Console
# 1. Go to https://search.google.com/search-console
# 2. Select property
# 3. Sitemaps → Add new sitemap
# 4. Enter: sitemap.xml
 
# Bing Webmaster Tools
# 1. Go to https://www.bing.com/webmasters
# 2. Submit sitemap URL
 
# Programmatic submission (ping)
curl "https://www.google.com/ping?sitemap=https://example.com/sitemap.xml"
curl "https://www.bing.com/ping?sitemap=https://example.com/sitemap.xml"

What NOT to Include

ExcludeReason
Noindex pagesWon't be indexed anyway
Duplicate contentMay cause issues
404/error pagesBad user experience
Login-required pagesCan't be indexed
Parameter variationsUse canonical URLs

Exceptions

  • Staging, utility, login, account, or internal search pages may intentionally use different crawl or index signals if they are not meant to rank.
  • Temporary migration states can produce noisy intermediate signals; flag the live production URL pattern, not one-off transition artifacts.
  • When redirects, canonicals, robots directives, or indexability signals conflict, fix the strongest final signal first instead of reporting every downstream symptom as a separate blocker.

Verification

Automated Checks

  • Validate XML format with online validators
  • Check Google Search Console sitemap status

Manual Checks

  • Access sitemap at yourdomain.com/sitemap.xml
  • Verify all important pages are included
  • Ensure URLs match canonical-url versions