Next.js Sitemap i robots.txt — automatyczna generacja z App Routera
Jak generować sitemap.xml i robots.txt w Next.js App Router? Natywne API konwencji plików vs next-sitemap — dynamiczne sitemaps, lastmod, changefreq i priorytety.
Sitemap to plik z listą ważnych URL-i, który pomaga wyszukiwarkom szybciej odkrywać i aktualizować podstrony..xml informuje wyszukiwarki o wszystkich stronach w serwisie — ich lokalizacji, dacie ostatniej modyfikacji i opcjonalnych wskazówkach, a plik Robots.txt to plik z dyrektywami dla crawlerów, który wskazuje, które ścieżki mogą lub nie powinny być odwiedzane. kontroluje, które ścieżki crawlery mogą swobodnie odwiedzać. Oba generujesz natywnym API, czyli Application Programming Interface, definiuje sposób komunikacji między aplikacjami lub modułami. Tu chodzi o konwencje plików Next.js, które zamieniają eksportowaną funkcję w gotowy plik sitemap.xml lub robots.txt. konwencji plików Next.js. Choć żaden z nich nie gwarantuje indeksacji ani jej blokady, są fundamentem technicznego SEO, czyli Search Engine Optimization, to optymalizacja strony pod widoczność w wynikach wyszukiwania..
Natywna sitemap w App Router
Statyczna sitemap
Najprostszym sposobem jest eksport tablicy obiektów z pliku sitemap.ts:
Code
// app/sitemap.tsimport type { MetadataRoute } from 'next'export default function sitemap(): MetadataRoute.Sitemap { return [ { url: 'https://strivelab.pl', lastModified: new Date('2025-01-15'), changeFrequency: 'monthly', priority: 1, }, { url: 'https://strivelab.pl/uslugi', lastModified: new Date('2025-01-15'), changeFrequency: 'monthly', priority: 0.9, }, { url: 'https://strivelab.pl/blog', lastModified: new Date('2025-03-01'), changeFrequency: 'weekly', priority: 0.8, }, { url: 'https://strivelab.pl/kontakt', lastModified: new Date('2025-01-15'), changeFrequency: 'yearly', priority: 0.5, }, ]}
Next.js generuje /sitemap.xml automatycznie.
Pułapka: lastModified: new Date() dla stron statycznych. Użycie new Date() (aktualny czas buildu) dla stron, które rzadko się zmieniają, spowoduje, że przy każdym deployu Google zobaczy nową datę modyfikacji. Może to zmylić crawlera i zmarnować Crawl budget to liczba i częstotliwość adresów URL, które robot wyszukiwarki jest skłonny odwiedzić w Twoim serwisie.. Dla stron statycznych używaj konkretnej daty lub pomijaj pole lastModified całkowicie. Dla treści z bazy danych pobieraj faktyczne pole updatedAt z rekordu.
changeFrequency i priority Google oficjalnie deklaruje, że oba pola traktuje tylko jako wskazówki i w praktyce je ignoruje. Z kolei inne wyszukiwarki (Bing, Yandex) mogą je uwzględniać, więc warto je wypełniać, ale nie skupiaj się na ich optymalizacji, kosztem innych działań SEO.
Dynamiczna sitemap — wpisy z CMS/bazy
Code
// app/sitemap.tsimport type { MetadataRoute } from 'next'import { db } from '@/lib/db'export default async function sitemap(): Promise<MetadataRoute.Sitemap> { const baseUrl = 'https://strivelab.pl' // Statyczne strony — konkretna data, nie new Date() const staticPages: MetadataRoute.Sitemap = [ { url: baseUrl, lastModified: new Date('2025-01-15'), changeFrequency: 'monthly', priority: 1, }, { url: `${baseUrl}/uslugi`, lastModified: new Date('2025-01-15'), changeFrequency: 'monthly', priority: 0.9, }, { url: `${baseUrl}/kontakt`, lastModified: new Date('2025-01-15'), changeFrequency: 'yearly', priority: 0.5, }, ] // Dynamiczne strony — posty blogowe const posts = await db.post.findMany({ where: { published: true }, select: { slug: true, updatedAt: true }, orderBy: { updatedAt: 'desc' }, }) const blogPages: MetadataRoute.Sitemap = posts.map((post) => ({ url: `${baseUrl}/blog/${post.slug}`, lastModified: post.updatedAt, // faktyczna data z bazy — poprawne changeFrequency: 'monthly' as const, priority: 0.7, })) return [...staticPages, ...blogPages]}
Wielojęzyczna sitemap z hreflang
Natywne API obsługuje pole alternates, służy do deklarowania wersji językowych strony, co Google wymaga przy implementacji hreflang:
Biblioteka next-sitemap oferuje dodatkowe funkcje, czyli automatyczne wykrywanie statycznie wygenerowanych stron po buildzie, wielojęzyczne sitemaps z hreflang, server-side sitemap regeneration i konfigurację per-ścieżka.
Dla większości projektów, zwłaszcza tych z przewidywalną strukturą, natywne API Next.js jest w zupełności wystarczające, prostsze i nie wprowadza dodatkowych zależności. Sięgnij po next-sitemap tylko w wyjątkowych sytuacjach, gdy masz bardzo duży, nietypowy serwis, gdzie automatyczne wykrywanie stron i zaawansowane transformacje oszczędzą Ci mnóstwa pracy manualnej.
Maciej Sala — project manager i frontendowiec z doświadczeniem w marketingu internetowym. Na co dzień pracuję z Reactem, Next.js i TypeScriptem, łącząc perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat związany z branżą gier wideo jako project manager i game designer.
Absolwent historii na Uniwersytecie Jagiellońskim i studiów podyplomowych z marketingu internetowego na Akademii Górniczo-Hutniczej w Krakowie. Poza pracą trenuje na siłowni, maluje figurki i realizuje własne projekty.
Jak korzystać z Google Search Console dla strony Next.js? Weryfikacja, sitemap, indeksacja, Core Web Vitals, crawl budget i najczęstsze problemy — praktyczny poradnik.
Jak poprawnie ustawić hreflang i canonical w Next.js App Router? Unikanie duplikacji treści, konfiguracja metadata API, wielojęzyczna sitemap i typowe błędy SEO.
Jak Next.js wpływa na SEO w praktyce? SSR, SSG, metadata, Core Web Vitals i techniczne ograniczenia, o których warto wiedzieć przed wyborem frameworka.