Modelowane listy odbiorców nie zawierają konkretnych osób, tylko prawdopodobieństwa. Wyjaśniam, jak powstają, gdzie ich szukać w panelu i jak czytać ich raporty.
Najbardziej frustrujące zgłoszenia, jakie dostaję, wyglądają tak: strona istnieje, otwiera się w przeglądarce, wygląda dobrze, a w Google jej nie ma albo w wynikach widnieje pusty tytuł i opis wzięty z niczego. Klient pokazuje mi ekran i pyta, czego jeszcze Google chce. Odpowiedź prawie zawsze brzmi: Google nie widzi tego, co widzisz Ty.
Nie ma w Google żadnego raportu o nazwie „błędy JavaScriptu”. To, co w praktyce nazywamy indykacją błędów, jest zbieraniem poszlak z kilku miejsc i składaniem ich w jeden obraz: co robot pobrał, co udało mu się wykonać i co ostatecznie trafiło do indeksu.
Poniżej opisuję, jak to robię — jakie narzędzia mam realnie do dyspozycji na koniec marca 2022, czego w nich nie znajdę i jakie wzorce w kodzie najczęściej odpowiadają za zniknięcie treści.
Warto rozdzielić trzy etapy, bo błąd na każdym z nich wygląda inaczej i inaczej się go naprawia.
Dobra wiadomość: od 2019 roku Google renderuje w aktualnej wersji Chromium, a nie w zamrożonym silniku sprzed lat. Nowoczesna składnia zadziała i nie trzeba transpilować kodu specjalnie dla robota.
Zła wiadomość: renderowanie to jedno podejście, bez ponowień na życzenie. Jeśli skrypt czeka na odpowiedź zewnętrznego API, które akurat zwróci błąd, albo treść pojawia się dopiero po interakcji użytkownika — do indeksu pójdzie strona bez tej treści. Nikt Ci o tym nie powie wprost.
Jest jeszcze kolejność, o której łatwo zapomnieć: jeśli w surowym HTML-u siedzi znacznik noindex, Google odrzuca stronę zanim ją wyrenderuje. Zdejmowanie go skryptem jest bezużyteczne.
Punktem wyjścia jest zawsze narzędzie sprawdzania adresu URL w Search Console. Wklejam adres, wybieram test na żywo, a potem klikam Wyświetl przetestowaną stronę — i to jest właściwy moment całej diagnostyki.
W zakładce z kodem HTML dostaję dokument po renderowaniu. Szukam w nim konkretnych rzeczy: nagłówka H1, głównego tekstu, listy produktów, linków w menu, znaczników danych strukturalnych. Jeśli w tym HTML-u nie ma zdania, na którym Ci zależy, to nie ma go w Google.
Zrzut ekranu obok traktuję jako drugi dowód. Zdarza się, że w kodzie treść jest, ale zrzut pokazuje białą stronę albo wieczny spinner — wtedy problem dotyczy raczej stylów niż samych danych.
Od stycznia tego roku te dane są dostępne także programowo, przez API narzędzia sprawdzania adresu URL. Przydaje się przy większych serwisach, bo pozwala odpytać wiele adresów zamiast klikać je pojedynczo. Warto jednak wiedzieć, czego z niego nie wyciągniesz: zwraca stan indeksowania i wynik testu, ale nie wyrenderowanego kodu ani zrzutu ekranu.
W tym samym oknie, w sekcji z dodatkowymi informacjami, są dwie listy, które w praktyce rozwiązują większość spraw.
Pierwsza to wiadomości konsoli JavaScript. Traktuję je jak log z awarii: jeden nieprzechwycony wyjątek w kodzie budującym listę produktów wystarczy, żeby cała lista nie powstała. Nie każdy komunikat jest winowajcą — ostrzeżenia o wycofanych metodach czy hałas z narzędzi analitycznych są zwykle nieszkodliwe.
Druga to zasoby strony, których nie udało się załadować, wraz z powodem. Tutaj wychodzą rzeczy najbardziej banalne: plik zablokowany w robots.txt, adres kierujący w pustkę po wdrożeniu nowej wersji, skrypt z zewnętrznej domeny odrzucający ruch robota. Jeżeli na tej liście jest plik, od którego zależy wyświetlenie treści, dalej nie muszę szukać.
Uzupełniająco używam testu optymalizacji mobilnej i testu wyników z elementami rozszerzonymi — oba pokazują wyrenderowany HTML i te same komunikaty, a działają bez dostępu do Search Console.
To wciąż numer jeden na liście przyczyn i najprostsza rzecz do sprawdzenia. Blokady w robots.txt są dziedziczone po latach i kopiowane z gotowców, w których ktoś kiedyś uznał, że robot nie musi zaglądać do katalogów technicznych. Efekt: Googlebot ma prawo pobrać HTML, ale nie pliki, które ten HTML dopiero wypełniają treścią. Nie zgłasza wtedy błędu — po prostu renderuje puste rusztowanie.
Sprawdzam trzy grupy reguł: katalogi ze skryptami i stylami, ścieżki z zasobami motywu i wtyczek, oraz adresy punktów końcowych API, z których strona pobiera dane. Ta trzecia bywa przeoczona, bo nie kojarzy się z zasobami na stronie, a bez niej lista produktów czy opinii nie powstanie.
Osobno pilnuję, żeby nie blokować adresów, które chcę usunąć z indeksu — blokada nie usuwa strony z wyników, tylko uniemożliwia odczytanie jej treści i znacznika noindex.
Poza awariami jest zestaw rozwiązań, które działają dla użytkownika i nie działają dla robota. Widzę je na większości serwisów opartych na frameworkach, które przejmuję do opieki.
W przeglądarce weryfikuję to szybciej: przełączam agenta użytkownika na Googlebota dla smartfonów, bo indeksowanie opiera się dziś na wersji mobilnej, i patrzę na panel sieci oraz konsolę.
Pojedynczy adres diagnozuję narzędziem sprawdzania URL. Skalę problemu widzę dopiero w raportach zbiorczych.
W raporcie Pokrycie patrzę na wykluczenia. Duża grupa adresów w stanie „Wykryto — obecnie nie zindeksowano” bywa objawem tego, że renderowanie tych stron nic sensownego nie zwraca. Podobnie masowe miękkie 404 przy adresach, które w przeglądarce wyglądają normalnie. To nie dowód, tylko wskazanie, gdzie kopać dalej.
W statystykach indeksowania szukam odpowiedzi serwera z podziałem na typy plików. Błędy przy plikach JavaScript i CSS to sygnał, że robot regularnie nie dostaje zasobów, których potrzebuje. Istotne są też wysokie czasy odpowiedzi — im dłużej trwa pobranie zasobu, tym większa szansa, że nie zmieści się w oknie renderowania.
Pamiętaj przy tym, że Google agresywnie buforuje pliki JavaScript i CSS i nie kieruje się Twoimi nagłówkami tak, jak przeglądarka. Po wdrożeniu poprawki robot może jeszcze korzystać ze starej wersji pliku — dlatego warto mieć skrót treści w nazwie.
Kolejność napraw wynika u mnie z kosztu i pewności efektu. Najpierw odblokowuję zasoby w robots.txt i naprawiam brakujące pliki, bo to zmiany małe i pewne. Potem usuwam błędy z konsoli, które wywalają budowanie treści. Dopiero na końcu wchodzę w architekturę.
Jeśli treść krytyczna dla wyszukiwarki powstaje wyłącznie w przeglądarce, wracam do rozmowy z programistami o renderowaniu po stronie serwera albo o generowaniu statycznych wersji podstron. Przy kilkunastu stałych podstronach byłoby to przerostem formy, przy katalogu z tysiącami produktów jest zwykle jedynym rozwiązaniem, które przestaje generować nowe problemy.
Dynamicznego renderowania dla robotów nie polecam jako celu. Google wciąż opisuje je jako obejście i tak też je traktuję: rozwiązanie awaryjne, kiedy przebudowa aplikacji jest niemożliwa w rozsądnym czasie.
I rzecz najważniejsza: naprawę trzeba potwierdzić tym samym narzędziem, którym wykryto problem. Wdrożenie poprawki nie kończy sprawy. Kończy ją wyrenderowany HTML, w którym widzę treść, oraz — po pewnym czasie — spadek liczby wykluczeń w raporcie. Bez tej pętli zostajesz z przekonaniem, że problem został rozwiązany, i bez żadnego dowodu.
Używamy plików cookies, aby ułatwić Ci nawigację oraz wykonywanie określonych funkcji. Szczegółowe informacje o wszystkich plikach cookies znajdziesz w każdej kategorii zgody poniżej.
Pliki cookies oznaczone jako "Niezbędne" są przechowywane w Twojej przeglądarce, ponieważ są one kluczowe dla zapewnienia podstawowych funkcji strony.
Używamy również plików cookies firm trzecich, które pomagają nam analizować, w jaki sposób korzystasz z tej strony, zapamiętują Twoje preferencje oraz dostarczają treści i reklamy odpowiednie dla Ciebie. Te pliki cookies będą przechowywane w Twojej przeglądarce tylko za Twoją uprzednią zgodą.
Możesz zdecydować, czy chcesz włączyć lub wyłączyć niektóre bądź wszystkie te pliki cookies, jednak wyłączenie niektórych z nich może wpłynąć na Twoje doświadczenia podczas przeglądania strony.
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __cf_bm | 13 minutes | Cloudflare bot management — distinguishes humans from bots. |
| rc::* | Persistent | Google reCAPTCHA — localStorage holding anti-bot challenge state. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| wpEmojiSettingsSupports | Session | WordPress — sessionStorage flag caching whether the browser can render emoji (feature detection). |
| ytidb* | Persistent | YouTube — IndexedDB storing playback/search state for embedded videos. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| _ga_* | 400 days | Google Analytics 4 — persists session state per property. |
| _ga | 400 days | Google Analytics — distinguishes unique users via a client id. |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| NID | 183 days | Google — stores preferences for personalized ads. |
| fr | 90 days | Meta — encrypted Facebook id and browser id for ads. |
| _gcl_au | 90 days | Google AdSense/Ads — experiments with advertising efficiency (conversion linker). |
| Cookie | Czas przechowywania | Opis |
|---|---|---|
| __Secure-YNID | 180 days | |
| YSC | Session | |
| __Secure-ROLLOUT_TOKEN | 180 days | |
| VISITOR_INFO1_LIVE | 180 days | |
| VISITOR_PRIVACY_METADATA | 180 days | |
| datr | 400 days | |
| sb | 400 days | |
| wd | 7 days |