Capítulo 143 de 456

sitemap.xml

Core Idea

sitemap.(xml|js|ts) gera um sitemap no formato Sitemaps XML para ajudar crawlers a indexar o site com mais eficiência.

Key Concepts

  • Estático: app/sitemap.xml direto no formato XML padrão.
  • Gerado: app/sitemap.ts default-exportando função que retorna um array MetadataRoute.Sitemap.
  • generateSitemaps: função para dividir um sitemap grande em múltiplos arquivos, retornando um array de { id }; cada id gera um sitemap em /.../sitemap/[id].xml.
  • Nesting: também é possível ter sitemap.xml em múltiplos route segments (ex.: app/sitemap.xml e app/products/sitemap.xml) como alternativa ao generateSitemaps.
  • images/videos: propriedades para gerar image sitemaps e video sitemaps.
  • alternates.languages: gera tags xhtml:link rel="alternate" para sitemaps localizados.

Code Examples

import type { MetadataRoute } from 'next'

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    { url: 'https://acme.com', lastModified: new Date(), changeFrequency: 'yearly', priority: 1 },
    { url: 'https://acme.com/about', lastModified: new Date(), changeFrequency: 'monthly', priority: 0.8 },
  ]
}
  • O que demonstra: sitemap gerado com changeFrequency e priority por URL.
export async function generateSitemaps() {
  return [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }]
}

export default async function sitemap(props: {
  id: Promise<string>
}): Promise<MetadataRoute.Sitemap> {
  const id = await props.id
  // Google's limit is 50,000 URLs per sitemap
  const start = id * 50000
  const end = start + 50000
  const products = await getProducts(
    `SELECT id, date FROM products WHERE id BETWEEN ${start} AND ${end}`
  )
  return products.map((product) => ({
    url: `${BASE_URL}/product/${product.id}`,
    lastModified: product.date,
  }))
}
  • O que demonstra: divisão de sitemap grande em múltiplos arquivos via generateSitemaps, respeitando o limite de 50.000 URLs do Google por sitemap.

Reference Tables

type Sitemap = Array<{
  url: string
  lastModified?: string | Date
  changeFrequency?: 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never'
  priority?: number
  alternates?: { languages?: Languages<string> }
  images?: string[]
  videos?: Videos[]
}>

Anti-patterns

  • Colocar mais de 50.000 URLs em um único sitemap: é o limite prático do Google; use generateSitemaps para dividir.
  • Ignorar id como promise em código novo: desde v16.0.0, id recebido por sitemap() é Promise<string>, precisa de await.

Key Takeaways

  1. sitemap.js é um Route Handler especial cacheado por padrão, a menos que use Request-time API ou dynamic config.
  2. Para apps grandes, prefira generateSitemaps a manter um único arquivo gigante.
  3. Localizações (alternates.languages) foram adicionadas na v14.2.0 e geram hreflang automaticamente.
  4. Sitemaps de imagem/vídeo (images, videos) seguem as specs do Google para esses formatos estendidos.

Connects To

  • generateSitemaps: função companheira para sitemaps múltiplos.
  • robots.txt: normalmente referencia a URL do sitemap gerado.