Kiedy crawl ze Screaming Froga to za mało. Historia Soft 404, którego nie widziało żadne narzędzie
Wyobraź sobie serwis, który z miesiąca na miesiąc zaczyna znikać z Google. Nie z dnia na dzień, nie z hukiem. Po prostu strony po cichu wypadają z indeksu. Otwierasz je w przeglądarce: działają. Sprawdzasz crawlerem: wszystko na zielono, kod 200, treść na miejscu. Wrzucasz adres do Google Search Console, klikasz „test live URL”, a Google renderuje stronę poprawnie. A mimo to w raporcie indeksowania rośnie liczba stron wyindeksowanych, oznaczonych jako Soft 404.
Brzmi jak sprzeczność? Bo jest. I to właśnie ta sprzeczność okazała się najciekawszym elementem całej sprawy.
Punkt wyjścia: serwis, który działa i znika jednocześnie
Klient to serwis średniej wielkości: strony ofertowe plus spore zaplecze contentowe, w sumie około kilkadziesiąt tysięcy adresów, zbudowany na nowoczesnym frameworku JavaScript. Pracowaliśmy razem już wcześniej, więc kiedy widoczność zaczęła się osuwać, temat trafił do mnie.
Skala problemu była poważna i nie pozostawiała złudzeń. To nie był spadek pozycji o kilka oczek. Strony wypadały z indeksu, a w dołku z serwisu wyparowała praktycznie cała widoczność organiczna. Poza stroną główną i zapytaniami o markę serwis przestał się w Google pokazywać na cokolwiek. Setki adresów, po cichu, tydzień po tygodniu.

A jednak, kiedy zaczynałem sprawdzać konkretne strony, wszystko wyglądało w porządku.
Paradoks: każde narzędzie mówiło „OK”
To jest moment, w którym większość audytów się kończy. I właśnie dlatego warto przy nim zostać.

Jak można mieć jednocześnie kod 200, poprawny HTML, działający podgląd w Search Console, a mimo to Soft 404? Każde narzędzie, które normalnie odpalasz, „kłamie” tak samo. Nie dlatego, że są zepsute, tylko dlatego, że wszystkie pokazują ten sam moment: stan strony tu i teraz. A problem nie był w tym, jak strona wygląda teraz.
I nie byłem pierwszy, który się temu przyglądał. Zanim temat trafił do mnie, klient poprosił o pomoc kilku specjalistów. Ich analizy kończyły się mniej więcej w tym samym miejscu: adresy zwracają 200, nie ma żadnych przekierowań na stronę błędu, nie wiadomo, co się dzieje. Padały też rekomendacje z zupełnie innej półki, które z tym problemem nie miały nic wspólnego. To nie zarzut wobec kogokolwiek. To miara tego, jak dobrze ten problem się chował: wszystkie standardowe tropy prowadziły donikąd.
Śledztwo, krok pierwszy: to, co sprawdza każdy
Zacząłem tak, jak zacząłby każdy. Soft 404 kojarzy się z jedną rzeczą: strona zwraca użytkownikowi komunikat „nie znaleziono”, ale z kodem 200 zamiast 404. Więc poszedłem po adresach artykułów, po requestach, logach i odpowiedziach serwera. Wszędzie 200. Czysto. Żadnych fałszywych „nie znaleziono”, żadnych podejrzanych przekierowań.
Ślepy zaułek? Tak, gdyby nie jeden akapit.
Kiedy w Search Console wszedłem głębiej w powód wyindeksowania, sięgnąłem po dokumentację Google. I tam, w dokumencie o kodach HTTP, jest zdanie, które łatwo przeoczyć: jeśli renderowana strona jest pusta lub prawie pusta, bo odwołuje się do zasobów, które nie mogą się załadować (obrazów, skryptów, plików CSS), Google może uznać ją za Soft 404.
Zasoby. Nie strona. Zasoby.
To jest cała różnica. Bo nikt sam z siebie nie sprawdza najpierw, czy to nie pliki JavaScript i CSS zwracają 404. Sprawdza się adresy url artykułów, ofert itd. A ja przestałem patrzeć na adresy artykułów i zacząłem patrzeć na to, po co te strony sięgają, czyli na requesty do zasobów. I tam, na plikach skryptów, były ukryte 404.
Śledztwo, krok drugi: „ale u nas wszystko się ładuje”
Poszedłem z tym do zespołu deweloperskiego klienta. Reakcja była dokładnie taka, jakiej mógłbyś się spodziewać: „Sprawdzaliśmy, wszystkie zasoby się ładują.”
I oni mieli rację. U nich się ładowały. Otwierali stronę, patrzyli w narzędzia deweloperskie, pliki były na miejscu. Problem w tym, że „u nas działa” znaczyło „u nas, teraz”. A pytanie brzmiało inaczej: co widzi Google w chwili, w której on renderuje tę stronę, a nie w chwili, w której patrzy na nią deweloper?
To był drugi paradoks tej sprawy. Pierwszy: narzędzia mówią OK. Drugi: zespół, który zna ten kod na wylot, jest przekonany, że wszystko gra. Żeby ruszyć dalej, nie wystarczyło powiedzieć „a jednak nie działa”. Trzeba było udowodnić rozjazd w czasie, pokazać, że stan zasobów w chwili renderu po stronie Google był inny niż stan, który widzi deweloper teraz. Technika dowodzenia tego rozjazdu zostaje na osobną rozmowę, ale sprowadza się do jednego: poukładać zasoby i logi na wspólnej osi czasu.
Co się naprawdę działo: sekwencja, której nikt nie składa
Google nie renderuje JavaScriptu w tej samej chwili, w której pobiera stronę. Pobranie HTML i wykonanie skryptów to dwa osobne etapy, a wykonanie JS jest odroczone i przechodzi przez kolejkę renderu. Do indeksu trafia nie surowa odpowiedź serwera, tylko to, co zostanie z niej po renderze.
Żeby zrozumieć, co zepsuło układ, który wcześniej działał, poprosiłem zespół o listę wdrożeń z okresu, w którym zaczęły się problemy. I to spięło całość. W tym czasie zmienił się sposób, w jaki cache’owane były zasoby serwisu. Nie wchodzę tu w to dlaczego. Istotne jest, że ta zmiana pokryła się dokładnie z tym, co widziałem w logach: 404 na plikach, po które Google sięgał przy renderze.

Reszta układanki to już natura nowoczesnych frameworków JavaScript. Wersjonują one swoje pliki: każdy build dostaje nową nazwę z unikalnym hashem (to zresztą praktyka, którą sam Google zaleca). Przy każdym wdrożeniu stare pliki znikają, pojawiają się nowe. Dopóki wszystko dzieje się natychmiast, nikt tego nie zauważa. Ale kiedy Google pobiera stronę, odkłada jej render na później, a w międzyczasie na serwer wchodzi kolejny deployment, w chwili renderu Google sięga po nazwy plików, których już nie ma. Dostaje 404. Render się sypie. Do indeksu trafia pusta, „zepsuta” wersja strony, choć serwer cały czas grzecznie zwraca 200 z pełną treścią.
Naprawa, i dlaczego nie skończyła się na rekomendacji
Kierunek rozwiązania był jasny: zadbać o to, żeby zasoby, po które Google sięga przy opóźnionym renderze, były dostępne, a strona nie rozsypywała się, gdy jakiegoś pliku zabraknie.
Ale tu jest część, o której rzadko się pisze w case studies: rekomendacja to nie koniec pracy. Zdiagnozować problem to jedno. Przekonać zespół, który wciąż widzi „u nas działa”, i doprowadzić do wdrożenia, to drugie. Między jednym a drugim minęło sporo czasu i sporo rozmów. Widoczność nie wróciła w dniu, w którym oddałem diagnozę. Wróciła wtedy, gdy zmiany faktycznie weszły na produkcję.
Rezultat
Kiedy poprawki zostały wdrożone, widoczność zaczęła wracać. W dołku serwis praktycznie zniknął z wyników, bo poza stroną główną i frazami brandowymi nie rankował już na nic, a w kolejnych miesiącach odbudował widoczność niemal do poziomu sprzed spadku. Uczciwie dodam też, że w tym samym oknie czasu Google przechodził przez swoje aktualizacje, a część ruchu tła zawsze jest poza kontrolą pojedynczej naprawy. Ale kierunek i moment odbicia zgadzały się z wdrożeniem.
Co z tego wynika, nie tylko dla tego serwisu
Najtrudniejsze problemy techniczne w SEO to nie te, które psują jakiś punkt z checklisty. To te, w których każdy punkt z osobna jest spełniony, czyli kod 200, poprawny HTML, działający podgląd, zasoby ładujące się u dewelopera, a mimo to coś nie gra. Żeby je znaleźć, trzeba połączyć rzeczy, które normalnie leżą w osobnych szufladach: rytm wdrożeń, sposób, w jaki framework nazywa swoje pliki, kolejkę renderu Google i logi serwera. Żadne pojedyncze narzędzie nie patrzy na to wszystko naraz. Model AI zna każdą z tych reguł z osobna, ale nie złoży ich w tę konkretną, nietypową sekwencję bez kogoś, kto już widział, jak to się psuje. Czytaj – GPT czy Claude nie był w stanie zdiagnozować przyczyn problemu (i też wpłynęło to na moment, kiedy temat trafił do mnie – po kilku tygodniach).
Kilka wniosków, które możesz wyciągnąć z tego case’u:
- Kod 200 nie znaczy, że Google zobaczy poprawną stronę. Znaczy tylko, że serwer odpowiedział.
- To, co widzisz w teście teraz, nie musi być tym, co Google widzi w chwili renderu.
- Logi serwera potrafią powiedzieć więcej niż kolejny crawl, zwłaszcza gdy patrzysz nie na strony, a na zasoby, po które te strony sięgają.
- „U nas działa” to początek rozmowy, nie jej koniec.
Zakończenie
A może twój serwis też po cichu znika z Google, choć wszystkie narzędzia pokazują, że wszystko jest w porządku? Jeśli traci widoczność, a nikt nie potrafi wskazać przyczyny, bo na papierze każdy element się zgadza, to często znak, że problem leży tam, gdzie standardowa analiza nie zagląda. Chętnie sprawdzę, gdzie dokładnie. Zapraszam do kontaktu.
