seojuice

SEO w JavaScript: Jak sprawić, by aplikacja JS była indeksowana

Vadim Kravcenko
Vadim Kravcenko
· Updated · 9 min read

TL;DR: Google potrafi indeksować JavaScript, ale renderowanie po stronie klienta dokłada opóźniony krok pomiędzy crawlingiem a indeksowaniem. Umieść kluczową treść, metadane zależne od trasy oraz linki możliwe do przejścia (crawlable) w serwerowo renderowanym albo statycznym HTML-u. Następnie użyj narzędzia do sprawdzania adresu URL w Google Search Console, aby zweryfikować zrenderowane DOM, zasoby i błędy JavaScript — zamiast zakładać, że przeglądarka pokazuje dokładnie to, co Google otrzymało.

Jeśli Twoja aplikacja w React, Vue, Angular — albo niby server-rendered — nie pojawia się w Google, przestań pytać, czy Googlebot „obsługuje JavaScript”. Obsługuje. Pytanie brzmi, czy Google jest w stanie pobrać wymagane zasoby, uruchomić aplikację, odkryć jej linki i wygenerować DOM możliwy do indeksowania, zanim cokolwiek się wyłoży.

Model renderowania Co wysyła serwer Ryzyko SEO z JavaScriptem Najlepsze zastosowanie
SSG Wcześniej przygotowany HTML generowany w czasie builda Najniższe. Treść jest dostępna w początkowej odpowiedzi. Artykuły, dokumentacja, strony marketingowe, katalogi oraz w miarę stabilne treści publiczne.
SSR HTML generowany na serwerze dla każdego żądania Niskie. Roboty mogą odczytać kluczową treść bez uruchamiania JavaScriptu. Dynamiczne strony publiczne, które potrzebują świeżego albo zależnego od żądania HTML-a.
CSR Minimalna „otoczka” HTML plus paczki JavaScript Najwyższe. Treść i linki zależą od tego, czy opóźnione renderowanie powiedzie się do końca. Uwierzytelnione dashboardy i obszary interaktywne, które nie muszą bazować na organicznym wyszukiwaniu.
Dynamic rendering Różne wyniki dla botów i użytkowników Składnikowo i operacyjnie złożone — Google przestało to rekomendować. Starsze systemy czekające na poprawkę architektury, a nie nowe wdrożenia.
To, co widzi Googlebot, zależy od tego, gdzie renderujesz: po stronie klienta to ryzyko, renderowanie po stronie serwera lub statyczne jest bezpieczniejsze.

Pipeline, który musi przetrwać Twoja aplikacja w JavaScripcie

Google Search Central opisuje przetwarzanie JavaScriptu w trzech odrębnych fazach:

„Google przetwarza aplikacje internetowe w JavaScripcie w trzech głównych fazach: 1. Crawling 2. Renderowanie 3. Indeksowanie”

Najpierw Googlebot pobiera URL i analizuje odpowiedź. Jeśli ta odpowiedź jest prawie pusta i wygląda jak aplikacyjna otoczka, Google nie ma jeszcze kopii Twojego produktu, treści artykułu, nagłówków, metadanych generowanych po stronie klienta ani linków dla danej trasy. Ma URL, trochę htmlowej „scaffoldury” i odwołania do zasobów.

Później Google ustawia kwalifikujące się strony w kolejce do renderowania. W dokumentacji czytamy: „Strona może pozostać w tej kolejce przez kilka sekund, ale to może potrwać dłużej.” To dokładny model. Unikaj starego twierdzenia, że JavaScript zawsze tworzy opóźnienie indeksowania trwające dni lub tygodnie — Google tego nie mówi. Jest kolejka opóźniona, ale Twoja strona nadal musi zrenderować się poprawnie, gdy trafi na „front”.

Ta kolejka to etap, który deweloperzy często pomijają w głowie. W przeglądarce lokalnej aplikacja wygląda na kompletną, a pobrana odpowiedź może zawierać zaledwie element root i odwołania do paczek (view-source przydaje się tu, choć to tylko połowa diagnostyki).

Podczas renderowania Google uruchamia stronę w bezgłowym (headless) przeglądarce. Google potwierdza, że „Google Search uruchamia JavaScript, używając stałej (evergreen) wersji Chromium”. Wniosek: składnia współczesnych frameworków raczej nie jest głównym problemem. Lepszymi podejrzanymi są zablokowane zasoby, nieudane żądania API, wyjątki w runtime, treści sterowane interakcją oraz słaba semantyka i oznaczenie linków.

Po renderowaniu Google może przejrzeć wynikowy DOM i wyciągnąć URL-e dodane przez JavaScript. Te URL-e wracają do kolejki crawlingu. Indeksowanie dzieje się później. Nasze poradniki o tym, co znaczy crawling w SEO oraz jak działa indeksowanie w Google opisują granice między tymi etapami.

Możesz więc znać kategorię renderowaną po stronie klienta w Google jako URL, ale produkty, opisy i wychodzące linki mogą pozostać nieznane. Odkrycie (discovery) nie jest indeksowaniem. Zindeksowany URL nie jest też dowodem, że Google zobaczyło pełną stronę.

Która strategia renderowania JavaScript pasuje do jakiego zadania: CSR dla prywatnego UI aplikacji, SSR dla stron dynamicznych, SSG dla stabilnych treści, ISR dla dużych katalogów.

CSR działa, ale to kruchy domyślny wybór dla stron, które muszą się pozycjonować

Addy Osmani i Jason Miller definiują renderowanie po stronie klienta na web.dev jako renderowanie aplikacji w przeglądarce przez użycie JavaScriptu do modyfikowania DOM. Renderowanie po stronie serwera wysyła wygenerowany HTML z serwera. Renderowanie statyczne tworzy ten HTML w czasie builda. Hydration dodaje stan aplikacji i handlery zdarzeń do już istniejącego HTML-a.

Problem SEO z CSR ma charakter strukturalny, a nie ideologiczny. Twoja kluczowa treść nie trafia do początkowej odpowiedzi i zależy od tego, że inny system wykona później dodatkową pracę. To może działać świetnie. Ja nadal nie zrobiłbym z tego domyślnej zależności dla każdej publicznej trasy, jeśli HTML usuwa całe klasy potencjalnych awarii.

„Ogólnie rzecz biorąc, zachęcamy, aby deweloperzy rozważyli renderowanie po stronie serwera albo renderowanie statyczne zamiast podejścia o pełnej rehydratacji.”

To rekomendacja Osmaniego i Millera — a nie instrukcja, żeby każdą aplikację przerabiać na statyczną stronę. Prywatny dashboard analityczny ma inne wymagania niż publiczna kategoria marketplace. Renderuj to, co ma się pozycjonować, po stronie serwera albo w czasie builda, a potem dopiero dodaj interaktywność po stronie klienta tam, gdzie naprawdę ma sens.

Frameworki oferują kilka ścieżek do tej architektury. Nasz poradnik o SEO dla Next.js, React i Nuxt omawia decyzje specyficzne dla frameworków. Ale framework z obsługą SSR nie gwarantuje automatycznie, że dostaniesz wyjście serwerowo renderowane. Ja założyłem, że gwarantuje — i dopiero odkryłem, że użyteczne dane były nadal pobierane dopiero po mount (logo frameworka mnie nie uratowało).

Nie odświeżaj dynamic rendering

Dynamic rendering daje botom wstępnie zrenderowaną stronę, podczas gdy użytkownicy dostają aplikację JavaScriptową. Google opisywało to kiedyś jako obejście, ale obecne wskazówki są jednoznaczne:

„Dynamic rendering był obejściem, a nie długoterminowym rozwiązaniem problemów z treścią generowaną przez JavaScript w silnikach wyszukiwania.”

Dokumentacja Google dotycząca dynamic rendering rekomenduje zamiast tego renderowanie po stronie serwera, renderowanie statyczne albo hydration. Właśnie tam bym skierował czas inżynieryjny. Wykrywanie botów, osobne cache’e i dwie możliwe reprezentacje każdej strony zwiększają liczbę sytuacji, w których treść i metadane mogą się rozjechać.

Jeśli dynamic rendering już podtrzymuje działanie starszej strony, nie wyrywaj tego bez planu migracji. Po prostu nie myl tolerowanego obejścia z poprawną nową architekturą.

JavaScriptowe błędy SEO, które sprawdziłbym jako pierwsze

1. Kluczowa treść istnieje dopiero po wykonaniu JavaScriptu

Pobierz URL bez uruchamiania JavaScriptu. Jeśli odpowiedź zawiera tylko „root” aplikacji, komunikat ładowania i niewiele więcej, każde sensowne elementy są zależne od fazy renderowania po stronie Google. Przenieś główny tekst strony, nagłówki, rekordy produktów, treść artykułu oraz kluczową nawigację do wyjścia SSR lub SSG.

Nie musisz usuwać JavaScriptu. Potrzebujesz użytecznej bazy w HTML. Gdzie to ma sens, zostaw filtry, kalkulatory, stan konta i kontrolki interaktywne po stronie klienta. Miarą jakości jest prosty test: jeśli główna paczka (main bundle) się nie powiedzie, czy odpowiedź nadal wyjaśnia, co ten URL zawiera?

Testuj reprezentatywne szablony, a nie jeden przypadkowo wygodny URL. Strona główna może być statyczna, a strony kategorii pobierają dane dopiero po mount. Strony produktów mogą używać SSR, a trasy z filtrem mogą zwracać tylko generyczną otoczkę. Jedna przechodząca strona udowadnia mniej, niż większość zespołów chciałaby, żeby udowodniła.

Naprawiam to zanim zaczniemy dopieszczać metadane. Tytuł z serwera nie zrekompensuje pustego ciała artykułu. Z drugiej strony, kompletna treść nadal jest w opałach, jeśli Google dostaje niekończący się stan ładowania. Najpierw architektura.

2. „Twoje linki” są w rzeczywistości handlerami zdarzeń

To jedna z najczęstszych usterkek, jakie widzimy na stronach podłączonych do SEOJuice. Karta albo pozycja menu wywołuje metodę routera, ale w markupie nie ma prawdziwego elementu anchor ani docelowego adresu. Zachowuje się jak nawigacja dla człowieka. Nie jest to jednak link możliwy do crawlowania.

Google podąża za prawdziwymi kotwicami (anchor), a nie za handlery clicka:

<!-- Crawlable: prawdziwy link, który Google może śledzić -->
<a href="/products/blue-widget/">Blue Widget</a>

<!-- Niewidoczne dla crawlowania: w ogóle nie jest linkiem -->
<div onclick="navigate('/products/blue-widget/')">Blue Widget</div>
„Google może odkryć Twoje linki tylko wtedy, jeśli są to elementy HTML typu <a> z atrybutem href.”

To sformułowanie pochodzi wprost z Google Search Central. Nawigowalne destynacje powinny używać prawdziwych kotwic z href. Router może dalej przechwytywać kliknięcie i robić nawigację po stronie klienta; progressive enhancement i zachowanie typowe dla SPA są w pełni kompatybilne.

Szkoda się kumuluje. Jeśli listing wyświetla 100 klikalnych kart jako przyciski albo divy, to tych 100 destynacji nie ma w mechanizmie odkrywania linków, który Google dokumentuje (sitemap może ujawnić URL-e, ale nie naprawi relacji linkowania wewnętrznego).

Sprawdź menu, karty, paginację, breadcrumbs, moduły „related content”, filtry o stabilnych destynacjach i nawigację po logo. Jeśli całe grupy tras są nieobecne w Google, zrób audyt linków z już znanych stron, zanim obwinisz indeksowanie. Nasz przewodnik po najlepszych praktykach SEO dla SPA wchodzi głębiej w odkrywanie tras oraz nawigację po stronie klienta.

3. robots.txt blokuje zasoby JavaScript, CSS lub API

Google stwierdza, że Search nie renderuje JavaScriptu z zablokowanych plików ani na zablokowanych stronach. Przejrzyj szerokie reguły robots.txt pod kątem ścieżek do assetów, takich jak /static/, /_next/, katalogi builda oraz proxywane endpointy API potrzebne do zbudowania publicznej treści.

Zajrzyj w wdrożone URL-e zasobów, zamiast ufać konfiguracji repozytorium. Reguła CDN, robots plik specyficzny dla środowiska, check uwierzytelnienia albo przestarzała ścieżka wdrożenia mogą sprawić, że produkcja zachowuje się inaczej niż lokalny development (produkcja bywa zaskakująco kreatywna).

Upewnij się też, że zasoby zwracają Googlebotowi użyteczne odpowiedzi. Paczka zwracająca 403, wywołanie API nieudane bez cookie sesji albo wygasły URL fragmentu (chunk) mogą zostawić crawlera z pustą otoczką, nawet jeśli robots.txt wygląda „czysto”.

4. Kluczowa treść wymaga interakcji

Treści pobierane dopiero po wybraniu zakładki, kliknięciu „Load more”, wywołaniu żądania zależnego od scrolla albo po udzieleniu zgody na pewno nie muszą pojawić się w DOM, który Google indeksuje. Dokumentacja troubleshooting Google mówi deweloperom, by „oczekiwali, że Googlebot będzie odrzucać prośby o zgodę użytkownika”.

Udostępnij treści możliwe do indeksowania bez wymagania ścieżki użytkownika. Treści paginowane powinny mieć stabilne URL-e i linki możliwe do crawlowania. Jeśli zakładka zawiera odrębne informacje, które warto indeksować, uwzględnij je w początkowym HTML albo podaj crawlable destynację. Crawler nie powinien musieć symulować użycia produktu, żeby dostać Twoją kluczową treść.

5. Router pokazuje 404, a serwer zwraca 200

SPA może wyświetlić dopracowany komponent „Nie znaleziono” dla nieprawidłowej trasy, podczas gdy serwer raportuje 200 OK. Google traktuje to jako wzorzec soft-404. Udokumentowane rozwiązania to przekierowanie na URL, gdzie serwer zwraca prawdziwe 404, albo dodanie albo zmiana metatagu robots na noindex.

Wolę prawidłowy status serwera wszędzie tam, gdzie stack na to pozwala. Kody statusu komunikują, co się stało, zanim aplikacja w ogóle wystartuje. Są też dużo łatwiejsze do monitorowania niż stan routera.

Sprawdź błędnie zbudowane URL-e produktów, usunięte rekordy, nieprawidłową paginację, niepoprawne trasy locale oraz catch-all pathy. To są edge case’y, które często dziedziczą ten sam app shell co poprawne strony i cicho tworzą tysiące „udanych” URL-i błędów.

6. Hydration psuje poprawny HTML zwrócony przez serwer

SSR może zwrócić kompletny HTML i mimo to wyłożyć się dopiero po załadowaniu. web.dev podkreśla, że kontrolki renderowane po stronie serwera nie mogą reagować, dopóki nie uruchomią się skrypty po stronie klienta i nie podłączą handlerów zdarzeń. Wyjątek w hydration może zostawić użytkownika z martwymi kontrolkami; mismatch może podmienić albo usunąć treść, która istniała już w odpowiedzi.

Porównaj trzy stany: surowy HTML, DOM przeglądarki po hydration oraz zrenderowany DOM Google. Jeśli surowa odpowiedź jest poprawna, a zrenderowany DOM traci treść, to przejście na SSR nie rozwiązało całego problemu — tylko przeniosło awarię dalej.

7. Tytuły, canonicale i opisy trafiają za późno

Google potwierdza, że JavaScript może ustawiać albo zmieniać tytuł i meta description. Mimo to metadane zależne od trasy powinny trafiać do serwera lub statycznej odpowiedzi, gdy tylko jest to praktyczne. Jeśli renderowanie się nie powiedzie, Google może trafić na generyczny tytuł aplikacji zamiast wersji właściwej dla strony.

Zastosuj tę samą dyscyplinę do tagów canonical i dyrektyw robots. Zmiany po stronie klienta mogą zostać przetworzone, ale uzależnienie krytycznych sygnałów indeksowania od wykonania daje niewiele i tworzy kolejne miejsce, w którym błędy routingu mogą „przeciekać” między szablonami.

Jak zobaczyć, co Google faktycznie zrenderowało

Narzędzie do sprawdzania adresu URL w Google Search Console jest rozstrzygającą kontrolą. Testy w przeglądarce, lokalny crawler i uruchomienia Lighthouse mogą wykryć usterki, ale żadne z nich nie odwzorowuje wyniku zapisanego przez Googlebota.

  1. Sprawdź dokładny kanoniczny URL. Nie testuj tylko strony głównej, jeśli brakujące strony korzystają z innego szablonu albo innej ścieżki pobierania danych.
  2. Otwórz „View Crawled Page”. Dla strony, która jeszcze nie jest zindeksowana, użyj „Test Live URL” i przejrzyj wynik z testu.
  3. Przeczytaj zrenderowany HTML. Wyszukaj charakterystyczne zdanie z kluczowej treści, tytuł specyficzny dla trasy, canonical URL oraz linki do głębszych podstron.
  4. Sprawdź zrzut ekranu. Puste rooty, stany ładowania, nakładki zgody i brakujące sekcje mogą szybko ujawnić nieudany render.
  5. Przejrzyj komunikaty konsoli i zasoby strony. Szukaj wyjątków, zablokowanych paczek, nieudanych wywołań API i błędów ładowania chunków.
  6. Porównaj z surową odpowiedzią. Pobierz URL przy pomocy klienta HTTP w linii poleceń. Różnica pomiędzy HTML-em odpowiedzi a zrenderowanym HTML-em Google pokazuje zależność od JavaScriptu, którą trzeba ocenić.

JavaScript troubleshooting guide Google mówi, że te narzędzia pokazują załadowane zasoby, wyjście konsoli JavaScript i wyjątki, zrenderowany DOM oraz inne informacje diagnostyczne. Jeśli w tym DOM brakuje ważnego akapitu albo linku, to czekanie na pozycje nie jest strategią testową. Napraw ścieżkę renderowania.

W SEOJuice jesteśmy dwuosobowym zespołem: Lida i ja. Bezpośrednia inspekcja ma znaczenie, bo nie możemy pozwolić sobie na zamienianie każdego problemu indeksowania w tydzień spekulacyjnego debugowania. Surowy HTML, zrenderowany HTML, zasoby, konsola. Cztery sprawdzenia szybko zawężają problem.

Różnicę zobaczyliśmy bardzo jasno podczas migracji seojuice.io → seojuice.com w styczniu 2026. Strony wyglądały poprawnie w zwykłej przeglądarce i testy na żywo mogły przejść, podczas gdy zapisane crawle Google dla części tras jeszcze nie nadążały. Udany test na żywo dowodzi, że Google potrafi zrenderować stronę w czasie testu; nie przebudowuje historycznych crawlów ani nie gwarantuje indeksowania (chciałbym, żeby ten przycisk też działał).

Praktyczny „release gate” dla stron z indeksowalnym JavaScriptem

Nie traktuj SEO dla JavaScriptu jak sprzątania po wdrożeniu. Dodaj mały próg wydania dla każdego publicznego szablonu:

  • URL zwraca zamierzony kod statusu bez polegania na routingu po stronie klienta.
  • Surowy HTML zawiera główny nagłówek, kluczową treść i metadane zależne od trasy.
  • Nawigacja używa elementów kotwicy (anchor) z atrybutami href.
  • JavaScript, CSS oraz wymagane publiczne zasoby danych są crawlable.
  • Strona pozostaje użyteczna, jeśli hydration się nie powiedzie.
  • Zrenderowany DOM zawiera tę samą kluczową treść i sygnały indeksowania co odpowiedź.
  • Niewłaściwe i usunięte trasy zwracają prawdziwą odpowiedź błędu albo celową dyrektywę noindex.

To nie jest prośba o HTML 1:1 co do pikseli. Stan interakcji może się różnić. Wymaganie jest proste: znaczenie strony, odkrywalne destynacje i instrukcje indeksowania muszą przeżyć każdą fazę w pipeline Google.

Gdzie SEOJuice się sprawdza, a gdzie nie

SEOJuice działa na działającej stronie poprzez snippet JavaScript albo wtyczkę w CMS. Ciągle wykonuje prace on-page, takie jak linki wewnętrzne, tytuły i opisy meta, schema markup oraz tekst alternatywny dla obrazków. Audyt może też ujawnić brakujące metadane, zbyt cienką albo brakującą zrenderowaną treść, zablokowane zasoby, wzorce linków niedostępne do crawlowania oraz luki w indeksowaniu.

Nie zamienia aplikacji CSR w SSR. Ponieważ snippet działa po stronie klienta, jego wynik jest współzależny od renderowania opisanego wyżej. Jeśli kluczowa treść nie pojawia się w HTML-u, najpierw napraw architekturę renderowania; automatyzacja powinna siedzieć na wierzchu strony, którą Google może niezawodnie przetworzyć.

Jeśli aplikacja renderuje się poprawnie i chcesz wskazać pozostałe błędy on-page oraz problemy z indeksowaniem, uruchom darmowy audyt SEO. Darmowy plan jest dostępny bez karty kredytowej.

Najczęściej zadawane pytania

Czy Google indeksuje JavaScript?

Tak. Google Search wykonuje JavaScript przy użyciu evergreen wersji Chromium. Strony w JavaScript nadal przechodzą przez opóźnioną fazę renderowania, więc treść może się opóźniać albo umykać, jeśli zasoby są zablokowane, wykonanie się nie powiedzie lub ważne informacje wymagają interakcji użytkownika.

Dlaczego moja aplikacja React, Vue lub Angular nie jest widoczna w Google?

Najczęstsza przyczyna nie leży w samym frameworku. Sprawdź, czy kluczowa treść i linki istnieją dopiero po wykonaniu po stronie klienta, czy paczki albo API nie są dostępne dla Googlebota oraz czy błędy w runtime nie blokują renderowania. Dodatkowo przejrzyj soft 404, generyczne metadane ustawiane po stronie klienta oraz nawigację bez prawdziwych kotwic.

Jaka jest różnica między SSR, SSG i CSR pod kątem SEO?

SSG generuje HTML w czasie builda. SSR generuje HTML na serwerze dla każdego żądania. Oba podejścia ujawniają kluczową treść w odpowiedzi. CSR składa stronę w przeglądarce, co uzależnia ją od późniejszego renderowania przez Google. Dla publicznych stron, które mają się pozycjonować, SSG albo SSR zazwyczaj jest bezpieczniejszym domyślnym wyborem.

Czy Google nadal rekomenduje dynamic rendering?

Nie. Google nazywa dynamic rendering obejściem, a nie rozwiązaniem długoterminowym. Aktualne wskazówki kierują deweloperów w stronę renderowania po stronie serwera, statycznego renderowania lub hydration. Nie zaczynaj nowej implementacji opartej na osobnym wyjściu dla botów i użytkowników.

Czy JavaScriptowe przyciski i nawigacja przez onClick liczą się jako linki?

Nie jako linki możliwe do crawlowania. Google dokumentuje odkrywanie linków poprzez elementy kotwic (anchor) z atrybutem href. Używaj semantycznych kotwic dla destynacji możliwej do nawigacji, nawet jeśli router po stronie klienta przechwytuje zdarzenia, żeby uniknąć pełnego przeładowania strony.

Jak zobaczę, co zrenderował Googlebot?

Sprawdź dokładny URL w Google Search Console, otwórz stronę z crawla albo przetestowaną na żywo, a potem przejrzyj jej zrenderowany HTML, zrzut ekranu, załadowane zasoby oraz komunikaty konsoli JavaScript. Przeszukaj HTML pod kątem kluczowej treści i linków wewnętrznych. Jeśli tam ich nie ma, to znaczy, że Google nie dostało kompletnej strony podczas tego testu.

Return the translated content in
SEOJuice
Stay visible everywhere
Get discovered across Google and AI platforms with research-based optimizations.
Works with any CMS
Automated Internal Links
On-Page SEO Optimizations
Get Started Free

no credit card required

More articles

No related articles found.