Kamil Owczarek
Opublikowano

Bug w sitemapie, który ukrył wszystkie nasze produkty przed Google

Autorzy

Odkrycie: gdzie podziały się nasze produkty?

W zeszłym tygodniu przeglądałem nasze Google Search Console i coś mi nie grało. Nasz sklep e-commerce ma tysiące produktów, setki artykułów, dziesiątki stron z inspiracjami — a liczba zaindeksowanych stron była podejrzanie niska.

Otworzyłem naszą sitemapę pod /sitemap.xml i zacząłem drążyć. Wtedy zauważyłem coś dziwnego: w sitemapie były wyłącznie strony kolekcji. Produkty, aktualności, inspiracje, kategorie, projektanci — wszystkiego brakowało.

Obsługujemy 11 rynków międzynarodowych ze zlokalizowanymi URL-ami. Tysiące stron po prostu... zniknęły z radaru Google.

Śledztwo: zwykła lista wykluczeń

Nasz nuxt.config.ts miał konfigurację sitemapy, która wyglądała rozsądnie:

// nuxt.config.ts - The problematic configuration
sitemap: {
  exclude: [
    '/dashboard/**',
    '/product/**',
    '/news/**',
    '/faq/**',
    '/inspirations/**',
    '/bathroom/**',
    '/kitchen/**',
    '/designers/**',
    '/list-of-landings/**',
    '/satisfaction-survey/**',
    '/clipboard',
  ],
  cacheMaxAgeSeconds: 86400,
}

Chwila, dlaczego wykluczaliśmy /product/**? To wyglądało źle. I tu robi się ciekawie — te wykluczenia zostały dodane pierwotnie po to, żeby zapobiec dynamicznemu generowaniu tras dla stron, które miały własne źródła w sitemapie.

Rozumowanie było takie: "nie generujmy tych URL-i automatycznie, bo dodajemy je ręcznie przez sitemap sources". Brzmi rozsądnie, prawda?

Nieprawda.

Źródło problemu: ukryte zachowanie i18n w Nuxt Sitemap

Oto co robi moduł @nuxtjs/sitemap, a co nie wynika wprost z dokumentacji:

Kiedy masz skonfigurowane i18n, wzorce wykluczeń są automatycznie rozwijane na wszystkie prefiksy językowe.

Więc to:

exclude: ['/product/**']

Po cichu staje się tym:

exclude: [
  '/product/**', // Polish (default, no prefix)
  '/en/product/**', // English
  '/de/product/**', // German
  '/uk/product/**', // Ukrainian
  '/ru/product/**', // Russian
  '/hu/product/**', // Hungarian
  '/ro/product/**', // Romanian
  '/fr/product/**', // French
  '/sl/product/**', // Slovenian
  '/it/product/**', // Italian
  '/es/product/**', // Spanish
]

Każdy pojedynczy URL produktu — w każdym języku — był wykluczany z sitemapy. To samo dotyczyło aktualności, inspiracji, kategorii i wszystkiego innego z tamtej listy.

Dlaczego kolekcje nadal działały

Rozgryźć to pomogła mi jedna poszlaka: kolekcje pojawiały się w sitemapie. Dlaczego?

Kolekcje używają polskiej struktury ścieżek: /kolekcja/[name] zamiast /collection/[name]. Ponieważ /kolekcja/** nie było na liście wykluczeń, te URL-e przetrwały.

To był moment olśnienia. Wykluczenie nie zawodziło po cichu — działało dokładnie tak, jak zostało zaprojektowane. To my nie zdawaliśmy sobie sprawy, do czego zostało zaprojektowane.

Naprawa: 9 usuniętych linijek

Rozwiązanie było wstydliwie proste:

// nuxt.config.ts - The fixed configuration
sitemap: {
  exclude: [
    '/dashboard/**',
    '/panel/**',
    '/clipboard',
  ],
  cacheMaxAgeSeconds: 86400,
}

I tyle. Usunąć zbyt szerokie wykluczenia. Zostawić tylko panele administracyjne i strony pomocnicze, które faktycznie nie powinny być indeksowane.

9 usuniętych linijek. Tysiące stron przywróconych do Google.

Co było potem

Po wdrożeniu poprawki:

  • Sitemapa wygenerowała się ponownie ze wszystkimi URL-ami produktów w 11 językach
  • Aktualności, inspiracje, kategorie i projektanci wrócili
  • Google Search Console zaczęło pokazywać oczekiwaną liczbę stron
  • Zgłosiliśmy prośby o ponowne zaindeksowanie priorytetowych stron

Strona chodziła z tą błędną konfiguracją przez tygodnie. To tygodnie nowych produktów, nowych artykułów i nowych treści, których Google nie widziało.

Wnioski

1. Wykluczenia w sitemapie są potężniejsze, niż wyglądają

W wielojęzycznej aplikacji Nuxt jeden wzorzec wykluczenia mnoży się przez liczbę twoich języków. Z wildcardami trzeba być wyjątkowo ostrożnym.

2. Sprawdzaj sitemapę ręcznie

Powinienem był regularnie zaglądać na /sitemap.xml. Zwykłe spojrzenie okiem wyłapałoby to natychmiast.

3. Kwestionuj odziedziczone konfiguracje

Ta lista wykluczeń została dodana wiele miesięcy temu w dobrej wierze. Ale pierwotny kontekst się zgubił i nikt nie zapytał, czy nadal ma sens.

4. Pułapka "u mnie działa"

Na środowisku deweloperskim możesz nie zauważyć problemów z sitemapą, bo nie sprawdzasz narzędzi SEO. Ten bug stał się widoczny dopiero przy analizie wyników SEO na produkcji.

Jak zweryfikować swoją sitemapę

Szybkie sprawdzenia, które możesz zrobić od ręki:

# Fetch your sitemap and count URLs
curl -s https://yoursite.com/sitemap.xml | grep -c "<loc>"

# Check for a specific path that should exist
curl -s https://yoursite.com/sitemap.xml | grep "product"

# If using sitemap index, check individual sitemaps
curl -s https://yoursite.com/sitemap_index.xml

W Nuxcie z i18n twój indeks sitemap powinien zawierać osobne sitemapy dla każdego języka:

  • /en-sitemap.xml
  • /de-sitemap.xml
  • i tak dalej

Upewnij się, że URL-e pojawiają się we WSZYSTKICH z nich, a nie tylko w języku domyślnym.

Wniosek na koniec

Czasem największe katastrofy SEO biorą się z najmniejszych zmian w konfiguracji. Dziesięciolinijkowa lista wykluczeń, dodana w dobrej wierze, przez tygodnie po cichu blokowała tysiące stron przed wyszukiwarkami.

Jeśli liczba twoich zaindeksowanych stron wydaje się niska, sprawdź najpierw konfigurację sitemapy. I pamiętaj: w wielojęzycznych aplikacjach Nuxt wzorce wykluczeń są dużo bardziej agresywne, niż się wydaje.


Prawdziwa historia debugowania z platformy e-commerce obsługującej 11 rynków europejskich. Naprawa zajęła 2 minuty. Znalezienie przyczyny — znacznie dłużej.