Boty AI nie wykonują JavaScriptu. Co widzą zamiast strony
Crawlery asystentów AI — GPTBot, ClaudeBot, PerplexityBot i pokrewne — pobierają surowy HTML i nie uruchamiają JavaScriptu, więc treść dorenderowywana w przeglądarce dla nich nie istnieje. W udokumentowanym na forum r/TechSEO przypadku z lipca 2026 strona cennika aplikacji SaaS w Reakcie miała w surowym HTML 194 słowa i zero kwot wobec 511 słów widocznych w przeglądarce. Sprawdzenie własnej strony zajmuje jedną komendę: pobrać ją curlem i zobaczyć, co zostaje bez przeglądarki.
Robert Marczyński6 min czytania6 źródeł
Test, który boli
Wyłącz JavaScript w przeglądarce i wejdź na własną stronę. To, co widzisz, jest wszystkim, co widzi asystent AI, kiedy ktoś pyta o Twoją firmę.
Na forum r/TechSEO pod koniec lipca 2026 opisano przypadek, który tę mechanikę pokazuje na liczbach — i przy okazji pokazuje, jak łatwo się w tym pomiarze pomylić. Aplikacja SaaS w Reakcie z prerenderowaną skorupą: nagłówek i śródtytuły były w dokumencie, reszta dokładana skryptem.
Zacznę od liczby, której nikt w wątku nie podważył, bo to ona rozstrzyga. Strona cennika: 194 słowa w surowym HTML wobec 511 po wyrenderowaniu i zero kwot — ceny dorenderowywał skrypt. Asystent zapytany o cennik nie ma czego przeczytać.
Z pomiarem strony głównej było gorzej i warto wiedzieć dlaczego. Najpierw padły liczby alarmowe: 228 znaków czytelnej treści na 19 tysięcy bajtów w tytule wątku, potem 300 słów wobec 1033 po wyrenderowaniu w komentarzu. Obie wzięły się z tego samego błędu — odczytu pustego kontenera Reacta zamiast sąsiadującego bloku prerenderu. Po sprostowaniu wyszło bliżej 617 słów według właściciela i 519 wobec 1032 według komentującego, który powtórzył skan. Różnica jest więc dwukrotna, nie kilkunastokrotna — a i tak wystarczyła, żeby model nie znał cennika.
To nie jest egzotyczny przypadek. Tak działa każda aplikacja renderowana wyłącznie po stronie klienta — a więc spora część stron zbudowanych w ostatniej dekadzie na React, Vue czy Angularze bez warstwy serwerowej.
Dlaczego boty nie renderują
Googlebot nauczył się wykonywać JavaScript, bo Google utrzymuje w tym celu osobną infrastrukturę renderującą — kosztowną i wolną, ale istniejącą. Crawlery asystentów AI poszły inną drogą: pobierają dokument i idą dalej.
Z dokumentacji OpenAI i Anthropic nie wynika, żeby GPTBot, OAI-SearchBot, ClaudeBot, Claude-User czy Claude-SearchBot renderowały strony; obserwacje praktyków z logów serwerowych — w tym wątki z r/TechSEO z 27–28 lipca 2026 — pokazują zgodnie żądania o sam HTML, bez pobierania i wykonywania skryptów. Ma to zresztą sens ekonomiczny: renderowanie milionów stron dziennie kosztuje wielokrotnie więcej niż ich pobranie, a boty odpowiadające na żywe pytania użytkowników nie mają na to czasu — odpowiedź powstaje w sekundy.
Konsekwencja jest binarna. Treść jest w dokumencie HTML albo nie istnieje. Nie ma „częściowo widoczna”, nie ma „bot się domyśli”.
Jak to sprawdzić u siebie
Najprościej wyłączyć JavaScript w przeglądarce i odświeżyć stronę: to, co zostaje, jest tym, z czego asystent może zbudować odpowiedź.
Test w terminalu wymaga jednej ostrożności, o której warto wiedzieć, zanim się go użyje. Samo curl … | wc -w policzy wszystko: znaczniki, atrybuty, wstawiony arkusz stylów i skrypty — na tej stronie zawyża czterokrotnie: liczy około siedmiu tysięcy „słów”, gdy realnej treści jest niecałe dwa tysiące. (Dokładne wartości zmieniają się przy każdej redakcji tego tekstu — dlatego podaję rząd wielkości, a nie liczbę do przepisania.) Żeby zmierzyć treść, trzeba najpierw odsiać skrypty i znaczniki:
curl -s https://twojadomena.pl | python3 -c "
import sys, re
t = sys.stdin.read()
t = re.sub(r'(?is)<(script|style)[^>]*>.*?</\1>', ' ', t)
print(len(re.sub(r'<[^>]+>', ' ', t).split()))"
Wynik porównaj z liczbą słów widocznych na ekranie. Jeżeli surowy dokument ma ich wyraźnie mniej — jak w przypadku z r/TechSEO, gdzie na stronie cennika brakowało wszystkich kwot — asystenci odpowiadają o Twojej firmie z okrojonej wersji strony albo wcale.
Drugi test celuje w to, co boli najbardziej: stronę z liczbami. Cennik, parametry, terminy. Tu jednak uwaga, na której sam się potknąłem: polski skład wstawia między liczbę a jednostkę twardą spację, więc grep '300 zł' ze zwykłą spacją nie znajdzie kwoty stojącej w treści. Na moim cenniku w widocznym tekście, po odsianiu znaczników i skryptów, ten wzorzec daje zero trafień — osiem, które łapie na surowym dokumencie, pochodzi z metaopisów i danych strukturalnych, nie z tabeli cen. Wzorzec dopuszczający twardą spację znajduje w treści dziesięć wystąpień: pięć kwot, każdą w tabeli i w odpowiedzi FAQ. Dlatego wzorzec musi dopuszczać oba znaki:
curl -s https://twojadomena.pl/cennik | python3 -c "
import sys, re
t = re.sub(r'(?is)<(script|style)[^>]*>.*?</\\1>', ' ', sys.stdin.read())
t = re.sub(r'<[^>]+>', ' ', t)
print(re.findall(r'[0-9][0-9\\s\\u00a0.,]*(?:zł|PLN)', t)[:10])"
Jeśli lista wróci pusta, a na ekranie kwoty są, wstawia je skrypt i bot ich nie zobaczy.
Ten serwis przechodzi oba testy: jest generowany statycznie, więc cała treść — z pięcioma kwotami cennika, które powyższa komenda znajduje w tabeli i w odpowiedziach — stoi w wysyłanym HTML, a strona działa także z całkowicie wyłączonym JavaScriptem. Wersja dla bota i wersja dla człowieka to ten sam dokument; skrypty, które framework dokłada, niczego do treści nie dopisują. To nie była decyzja estetyczna, tylko dokładnie ten rachunek.
Co zrobić, gdy strona jest po złej stronie granicy
Kolejność według kosztu i skutku.
Najtaniej: uzupełnić HTML tam, gdzie boli najbardziej. Jeżeli cała aplikacja jest kliencka, czasem wystarczy, żeby kilka stron krytycznych — oferta, cennik, kontakt — istniało jako strony statyczne z pełną treścią.
Docelowo: przenieść renderowanie na serwer (SSR) albo do builda (SSG). Frameworki, w których strony klienckie powstają, umieją to od lat; różnica nie wymaga zmiany technologii, tylko zmiany miejsca, w którym powstaje dokument.
Równolegle warto wiedzieć, dokąd zmierza konwencja, i rozróżnić dwie drogi, które łatwo pomylić. Cloudflare ogłosił w lutym 2026 „Markdown for Agents”: konwersję po stronie serwera, uruchamianą nagłówkiem Accept: text/markdown na tym samym adresie — agent prosi o markdown, sieć zamienia HTML w locie. W sierpniu 2026 wpisał ten mechanizm w szerszą wizję agentowego internetu. Prostszy wariant tej samej idei to bliźniak pod adresem z końcówką .md, publikowany jako zwykły plik statyczny. Ten serwis realizuje wariant prostszy: każda strona treściowa ma bliźniaka, ten tekst też — negocjacji nagłówkiem nie obsługujemy, bo wymagałaby funkcji działającej przy każdym żądaniu.
Na koniec proporcja, żeby nie przestrzelić w drugą stronę: to nie jest wezwanie do „optymalizacji pod boty”. To wezwanie do oddawania treści w dokumencie. Wszystko, co pisałem o wyborze źródeł przez modele, dzieje się dopiero wtedy, gdy bot ma co czytać.
Najczęstsze pytania
- Które boty AI nie wykonują JavaScriptu?
- Według zgodnych obserwacji praktyków z lipca 2026 dotyczy to całej klasy: GPTBot i OAI-SearchBot (OpenAI), ClaudeBot, Claude-User i Claude-SearchBot (Anthropic) oraz PerplexityBot. Pobierają dokument HTML takim, jakim odsyła go serwer, bez uruchamiania skryptów. Googlebot potrafi renderować JavaScript, ale to wyjątek z własną infrastrukturą renderującą, nie reguła dla botów AI.
- Jak sprawdzić, co bot AI widzi na mojej stronie?
- Najprościej wyłączyć JavaScript w przeglądarce i odświeżyć stronę — to, co zostanie, jest tym, z czego asystent może zbudować odpowiedź. W terminalu uważaj na skróty: samo `curl … | wc -w` liczy też znaczniki i skrypty, więc zawyża wynik kilkukrotnie. Sensowny pomiar wymaga odsiania skryptów i znaczników przed liczeniem, a najostrzejszy test to sprawdzenie, czy w surowym HTML strony cennika w ogóle są kwoty.
- Czy strona w React albo Vue jest niewidoczna dla AI?
- Nie sam framework decyduje, tylko sposób renderowania. Aplikacja renderowana wyłącznie po stronie klienta (CSR) jest dla botów AI pusta. Ten sam React z renderowaniem serwerowym (SSR) albo generowaniem statycznym (SSG) oddaje pełny HTML i jest widoczny w całości. Różnica nie dotyczy technologii, tylko miejsca, w którym powstaje dokument.
- Czy warto serwować botom osobną wersję strony?
- Rozsądniejsze jest serwowanie wszystkim tego samego pełnego HTML — to usuwa problem u źródła i nie ryzykuje rozjazdu wersji. Rosnącą praktyką uzupełniającą jest udostępnianie agentom tej samej treści w markdownie, tańszej w konsumpcji. Robi się to dwiema drogami: konwersją po stronie serwera na żądanie z nagłówkiem Accept: text/markdown (tak działa ogłoszony przez Cloudflare w lutym 2026 mechanizm Markdown for Agents) albo prościej — publikując bliźniaka pod adresem z końcówką .md.
Źródła
Dane zewnętrzne przywołane w tekście mają tu swoje źródła.
- r/TechSEO — obserwacje z logów: boty AI pobierają wyłącznie surowy HTML (27.07.2026)
- r/TechSEO — przypadek SaaS w React: cennik 194 słowa wobec 511 i zero kwot w surowym HTML; pierwotne 228 znaków i 300/1033 sprostowane w wątku do ok. 617 słów (właściciel) i 519/1032 (komentujący), 28.07.2026
- OpenAI — dokumentacja crawlerów (GPTBot, OAI-SearchBot, ChatGPT-User)
- Anthropic — dokumentacja crawlerów i skutki ich blokowania (ClaudeBot, Claude-User, Claude-SearchBot)
- Cloudflare — Introducing Markdown for Agents (12.02.2026)
- Cloudflare — standardy agentowego internetu (6.08.2026)
Udostępnij
Powiązane
- Jak modele AI wybierają źródła, które cytująW badaniu na dziewięciu modelach żaden z jedenastu fikcyjnych ekspertów, umieszczonych w ponad 600 artykułach…
- Jak przygotować dane firmowe do wdrożenia AI?Model językowy odpowiada z tego, co dostanie w zapytaniu, więc jakość wdrożenia zależy od tego, czy da się w firmowych zasobach…
- Czy llms.txt działa? Co mówią daneNa sierpień 2026 nie ma dowodów, żeby llms.txt wpływał na widoczność w wyszukiwarkach opartych na AI: Google dopisał w czerwcu…
Masz konkretny proces do omówienia?
Napisz, jaki to proces i ile razy w miesiącu się powtarza. Odpowiem, czy nadaje się do automatyzacji, również wtedy, gdy odpowiedź brzmi „nie warto”.
Albo prosto na adres: not-a-bot@