Mapa strony XML: pięć błędów, które znaleźliśmy we własnej

Mapa strony XML: pięć błędów, które znaleźliśmy we własnej

Ostatnio zweryfikowano: 29 września 2026
8 min czytania
Case study
Techniczne SEO
500+ projektów WP

Joost de Valk opublikował 27 września 2026 r. tekst o tym, że prawie nikt nie robi sitemap XML poprawnie. Przejrzał wtyczką Sitemap Inspector sześć serwisów, od Adobe po GOV.UK, i w każdym znalazł to samo: adresy z noindex, przekierowania, 404, kanoniczne wskazujące gdzie indziej, jedną datę na setki wpisów. Jego teza brzmi: „A sitemap should list the URLs a site wants indexed, and nothing else.”

Zgadzamy się z tezą i z listą. Sprawdziliśmy nią własny serwis. Między sierpniem a październikiem 2026 r. znaleźliśmy w generatorze sitemap wppoland.com pięć błędów, każdy zmierzony na produkcji. Trzy z nich lista Joosta by złapała. Dwóch nie złapie żaden inspektor, który czyta wpisy sitemapy, bo polegały na tym, czego w niej nie było. Ten tekst jest o obu rodzajach.

Kontekst techniczny: wppoland.com to serwis Astro w sześciu językach, około 6700 adresów w sitemapach. Sitemapy generuje własna integracja astro-sitemaps.mjs, nie wtyczka. To ważne dla wniosków: każdy z błędów poniżej siedział w kodzie, który czyta dane i buduje listę, a nie w samej liście.

#Błąd 1: data builda jako lastmod

24 sierpnia 2026 r. pięć różnych sitemap miało dokładnie jedną wartość lastmod na wszystkie wpisy, tę samą, dzisiejszą. Integracja liczyła new Date() raz i stemplowała nią 3079 adresów. Każde wdrożenie ogłaszało Google, że zmieniło się wszystko.

Google opisuje warunek wprost: używa <lastmod>, jeśli wartość jest „consistently and verifiably” zgodna z ostatnią zmianą strony (Google Search Central, strona o budowie sitemap, aktualizacja z 8 lipca 2026 r.). Data, która skacze przy każdym buildzie, tego warunku nie spełnia, więc Google przestaje jej ufać dla całej domeny, także tam, gdzie byłaby prawdziwa. W próbkach z tamtego okresu ostatni crawl niektórych stron sięgał od trzech tygodni do trzech miesięcy wstecz.

Naprawa podstawiła updatedDate z frontmattera, w razie braku pubDate. Efekt na artefakcie: polska sitemapa bloga przeszła z 1 na 98 różnych dat.

Przy tej naprawie łatwo o błąd drugiego rzędu. Kuszące było podstawienie pola lastVerified dla stron miast, bo ma je każdy z 4733 plików. Tyle że 4697 z 4733 plików ma w nim tę samą wartość. To zbiorczy stempel, nie sygnał, i przeniósłby ten sam defekt z „dzisiaj” na inną stałą datę. Zanim jakiekolwiek pole daty trafi do lastmod, trzeba policzyć, ile ma różnych wartości.

Naprawa z sierpnia objęła blog, portfolio i strony z kolekcji treści. Nie objęła ręcznie pisanych tras .astro. Artykuł Joosta skłonił nas do ponownego sprawdzenia: 29 września w /pl/sitemap-pages.xml 62 z 113 adresów nadal miało jako lastmod datę builda, bo nie istnieje dla nich data w treści, a kod spadał wtedy na today. Poprawka (commit af97c7a887) bierze dla takich tras datę ostatniego commita pliku źródłowego z jednego wywołania git log na build, a gdy i tej nie ma, pomija lastmod. Wspólny szablon [lang]/[slug].astro świadomie nie liczy się jako źródło, bo jego data nic nie mówi o żadnej konkretnej stronie. Ten sam plik po poprawce: 87 z 113 adresów ma lastmod, 42 różne daty, najczęstsza przypada na 7 adresów, a 26 adresów nie ma daty wcale. W polskiej sitemapie stron miast przed poprawką 684 z 692 wpisów miało datę builda, po niej 8 wpisów ma prawdziwą datę: szablon miast nie ma daty, której dałoby się uczciwie użyć, więc reszta daty nie deklaruje. Poprawka jest na produkcji od 29 września 2026 r., a żywy plik pokazuje te same liczby.

#Błąd 2: filtr noindex pilnował jednego pola

Po obniżeniu 723 stron miast do noindex Search Console dalej zgłaszał je jako odkryte. Same strony miały poprawny noindex. Wracały do Google inną drogą: sitemap-locations.xml wymieniała je jako alternatywy językowe (xhtml:link, także x-default) stron, które zostały w indeksie.

Filtr noindex w integracji sprawdzał tylko <loc>. Alternatywy pochodzą z nagłówka strony, który wymienia wszystkie wersje językowe, więc filtr ich nie widział. Poprawka zostawia tylko te alternatywy, których adres sam jest <loc> w sitemapie. Po niej build dawał 6407 adresów i 0 błędnych alternatyw.

Wniosek wykracza poza sitemapy: filtr na jednym polu wpisu nie obejmuje pozostałych pól tego wpisu, które niosą adres. W sitemapie takich miejsc jest kilka: loc, alternatywy, x-default, image:loc.

#Błąd 3: 500 działających stron poza sitemapą

21 września 2026 r. integracja zaczęła pomijać każdy adres pasujący do prefiksów, które middleware w functions/_middleware.ts przekierowuje. Tylko że middleware przekierowuje je wyłącznie wtedy, gdy zasób zwraca 404, a każdy kandydat do sitemapy jest zbudowaną stroną, więc nigdy nie zwraca 404. Filtr skopiował regułę bez jej warunku.

Wynik: 500 działających stron z index, follow wypadło z sitemapy, łącznie z celem jednego z przekierowań (/pl/audyt-bezpieczenstwa-wordpress/ pasował do prefiksu audyt-bezpieczenstwa-). Poprawka weszła 26 września, build z sitemapą dał +500 adresów i 0 usuniętych.

Tego błędu nie złapie żadna kontrola wpisów. Każdy z pozostałych adresów był poprawny: renderował się, nie miał noindex, nie przekierowywał. Mniej adresów w sitemapie wygląda jak porządki, a nie jak defekt. Wykryć to można tylko porównaniem zbioru adresów przed zmianą i po niej.

#Błąd 4: >- jako adres obrazka

Integracja wyciągała heroImage z frontmattera wyrażeniem regularnym, linia po linii. Przy bloku składanym YAML (heroImage: >-) wartość stoi w następnej linii, więc regex łapał dosłowne >-. Sitemapa dostawała wpisy <image:loc>https://wppoland.com/>-</image:loc>.

17 września 2026 r. na produkcji było 31 takich wpisów w sześciu językach. Search Console pokazywał pięć błędów na pl/sitemap-blog.xml, a sam XML był poprawnie zbudowany i każdy <loc> był w porządku. YAML w plikach też był poprawny. Zepsuty był czytający.

Poprawka parsuje frontmatter parserem YAML, a funkcję wyciągającą metadane wyeksportowaliśmy z integracji, żeby test mógł jej dosięgnąć bez pełnego builda. Wcześniej siedziała w środku 900-liniowego pliku i żaden test nie miał do niej dostępu.

#Błąd 5: IndexNow wysyłał adresy, których nie ma

Skrypt do IndexNow budował adresy z nazw plików w src/content/. 17 września 2026 r. generował 2328 adresów, z których 0 występowało w sitemapie. Wpisy bloga dostawały segment /blog/, którego w adresach nie ma, a strony zachowywały sufiks języka z nazwy pliku (/de/about.de/). Oba warianty zwracały 301. Do tego wzorzec plików łapał tylko .md, więc 100 filarów usługowych w .mdx nie było wysyłanych nigdy.

Poprawka jest jednym zdaniem: źródłem adresów do IndexNow jest sitemap-index.xml. Ten zbiór jest już sprawdzony: strony renderują się i nie mają noindex. Heurystyka z nazw plików zniknęła razem z trzema klasami błędów.

#Błąd bez błędu: Google nie pobrał sitemapy

Ten przypadek nie był defektem generatora, ale należy do tej samej rodziny. Na początku września 2026 r. po odblokowaniu stron miast sześć sitemap lokalizacji liczyło 4071 adresów. Wszystko po naszej stronie było poprawne: próbki zwracały 200 i index, follow, żaden adres z sitemapy nie był noindex ani przekierowaniem.

Search Console ostatni raz pobrał te sitemapy 1 września o 10:08, gdy miały 2037 adresów, i przez pięć dni ich nie odświeżył. Sitemapy bloga czytał codziennie. Wszystko dodane po tej godzinie dla Google nie istniało. Ponowne przesłanie przez API zostało pobrane tego samego dnia.

W kolejnym tygodniu liczba stron miast z wyświetleniami wzrosła z 223 do 343, a ich wyświetlenia z 1570 do 4382. Te 343 strony to 8,4 procent z 4071 i w siedem dni dały 2 kliknięcia. Odblokowane zostało odkrycie, nie ruch, i to są dwie różne liczby.

#Czego inspektor wpisów nie zobaczy

BłądJak wyglądał w sitemapieCzy wykryje go kontrola wpisówCo go wykryło
Data builda jako lastmodwszystkie wpisy z jedną datątak, jako powtarzający się lastmodliczba różnych dat w pliku
Alternatywy obok noindexpoprawne <loc>, błędne xhtml:linkczęściowo, jeśli sprawdza alternatywyraport Search Console o noindex
500 stron poza sitemapąkażdy obecny wpis poprawnynieporównanie zbioru adresów przed i po
>- jako obrazek31 błędnych image:loctak, jeśli sprawdza obrazkibłędy sitemap w Search Console
IndexNow spoza sitemapysitemapa poprawnanie, błąd poza sitemapąprzecięcie listy wysyłki z sitemapą
Sitemapa niepobranaplik poprawny i aktualnyniedata pobrania w Search Console

Wtyczka taka jak ta, której użył Joost, odpowiada na pytanie „czy to, co jest w sitemapie, jest poprawne”. To dobre pytanie i większość serwisów, jak pokazał, na nie nie odpowiada. Ale trzy z sześciu naszych przypadków dotyczyły czego innego: czego w sitemapie nie ma, co z niej korzysta i którą wersję widzi Google.

#Lista kontrolna dla generatora sitemap

Kontrola wpisów jest warunkiem koniecznym, nie wystarczającym. Te pięć punktów sprawdza generator, a nie sam plik:

  1. Policz różne wartości lastmod w każdym pliku. Jedna wartość na setki wpisów oznacza stempel, nie datę. To samo przed podstawieniem nowego pola daty: jeśli prawie wszystkie pliki mają w nim tę samą wartość, pole nie nadaje się na lastmod. Brak lastmod jest lepszy niż nieprawdziwy.
  2. Porównuj zbiór adresów przed zmianą generatora i po niej. Liczba dodanych i usuniętych adresów, z listą. Spadek liczby adresów wymaga wyjaśnienia tak samo jak wzrost.
  3. Każde pole niosące adres podlega tym samym filtrom. loc, alternatywy językowe, x-default, image:loc. Filtr na jednym z nich nie chroni pozostałych.
  4. Reguła skopiowana z innego komponentu przychodzi razem ze swoim warunkiem. Przekierowanie „gdy 404” to nie to samo co przekierowanie zawsze.
  5. Sitemapa jest jedynym źródłem adresów dla wszystkiego, co wysyła adresy dalej: IndexNow, Indexing API, listy do ręcznego zgłoszenia. I raz na tydzień: data ostatniego pobrania w Search Console i liczba adresów, którą tam widać, obok liczby <loc> w żywym pliku.

Dwie rzeczy z dokumentacji Google, które warto mieć pod ręką: jeden plik sitemapy mieści najwyżej 50 000 adresów lub 50 MB bez kompresji, a wartości <priority> i <changefreq> są ignorowane. Nie szkodzą, ale nie warto nad nimi pracować.

Jeśli serwis działa jako headless WordPress, dochodzi pytanie, kto w ogóle generuje sitemapę, front czy WordPress. Opisaliśmy to osobno w tekście o sitemapie i kanonicznym adresie w headless WordPress.

Następny krok

Przekuj artykuł w realne wdrożenie

Pod tym wpisem dokładam linki, które domykają intencję użytkownika i prowadzą dalej w strukturze serwisu.

Chcesz wdrożyć ten temat na swojej stronie?

Jeśli planujesz architekturę Headless WordPress, decoupling frontendu lub migrację na Astro, przygotuję architekturę, backend WP i superszybki frontend.

Powiązany klaster

Sprawdź inne usługi WordPress i bazę wiedzy

Wzmocnij swój biznes dzięki profesjonalnemu wsparciu technicznemu w kluczowych obszarach ekosystemu WordPress.

FAQ do artykułu

Często zadawane pytania

Najważniejsze odpowiedzi, które pomagają wdrożyć temat w praktyce.

SEO-readyGEO-readyAEO-ready4 Q&A
Czy lastmod może być datą builda?#
Nie. Google używa lastmod tylko wtedy, gdy wartość jest spójnie i weryfikowalnie zgodna z ostatnią zmianą strony. Data builda zmienia się przy każdym wdrożeniu, więc uczy Google, że sygnał nic nie znaczy. Lepiej pominąć lastmod niż podać nieprawdziwy.
Czy priority i changefreq w sitemapie mają znaczenie?#
Dla Google nie. Dokumentacja Google Search Central mówi wprost, że te wartości są ignorowane. Nie szkodzą, ale nie warto na nie poświęcać czasu.
Jak sprawdzić, czy Google widzi aktualną sitemapę?#
W Search Console porównaj datę ostatniego pobrania i liczbę wykrytych URL-i z liczbą elementów loc w żywym pliku. Rozjazd oznacza, że Google pracuje na starej wersji i nowe strony dla niego nie istnieją.
Skąd brać listę adresów do IndexNow?#
Z gotowej sitemapy, nie z nazw plików w repozytorium. Sitemapa jest już zbiorem stron, które renderują się i nie mają noindex. Adresy składane z nazw plików omijają trasy, slugi i przekierowania.

Potrzebujesz FAQ dopasowanego do branży i rynku? Przygotujemy wersję pod Twoje cele biznesowe.

Porozmawiajmy

Polecane artykuły