Googlebot i JSON-LD: jeden przebieg unescape
PL

Googlebot i JSON-LD: jeden przebieg unescape

Ostatnio zweryfikowano: 30 sierpnia 2026
11 min czytania
Przewodnik
PageSpeed 100/100
500+ projektów WP

Google przestał naprawiać Twoje dane strukturalne. Ekstrakcja JSON-LD stosuje teraz jeden przebieg odescapowania HTML, więc blok, który wcześniej był po cichu prostowany, dziś po prostu nie parsuje się i znika. Nie ma komunikatu o błędzie w Search Console, nie ma ostrzeżenia, jest tylko rich result, który przestaje się pojawiać. Ten tekst pokazuje, jak w kilka minut zmierzyć własny korpus zamiast zgadywać, gdzie w WordPressie ten zapis powstaje najczęściej i dlaczego jednorazowy audyt nie wystarczy. Nasz własny pomiar na 68 055 blokach jest w środku, razem ze skryptem.

#Co dokładnie zmienił Google

Komunikat jest krótki i wart zacytowania w całości, bo cała reszta to konsekwencje jednego zdania:

To bring our parser up to JSON and other standards, we changed our JSON-LD extraction and are now only applying a single pass of HTML unescaping

(Glosa: żeby dociągnąć parser do standardu JSON i innych standardów, Google zmienił ekstrakcję JSON-LD i stosuje teraz tylko jeden przebieg odescapowania HTML.)

Gary Illyes dorzucił wskazówkę, gdzie szukać definicji poprawności: RFC 8259, czyli specyfikacja formatu JSON. To nie jest wytyczna SEO, tylko odesłanie do standardu, który obowiązuje każdy parser JSON na świecie.

Praktyczny skutek opisano równie zwięźle: podwójnie zaescapowane encje, takie jak & czy ✔, nie będą już rozwijane. Wcześniej parser Google robił dodatkowy przebieg i taki zapis prostował. Teraz robi jeden przebieg i zostaje mu tekst, który nie jest poprawnym JSON-em.

Warto od razu nazwać to, czego w tej informacji nie ma. Nie ma daty wdrożenia. Nie ma linku do zaktualizowanej dokumentacji Google. Źródłem jest wpis na LinkedIn, relacjonowany przez Search Engine Roundtable 21 sierpnia 2026. Traktuj to więc jako stan zgłoszony przez Google, a nie jako zapis w dokumentacji, na który można się powołać przed klientem.

#Czym jest podwójne escapowanie i skąd się bierze

Weź prosty przypadek: nazwa firmy „Kowalski & Syn” w polu name w JSON-LD.

zapisco widzi parser JSONstatus
"Kowalski & Syn"Kowalski & Synpoprawny, ampersand nie wymaga ucieczki w JSON
"Kowalski & Syn"Kowalski & Synpoprawny, ucieczka uniwersalna
"Kowalski & Syn"Kowalski & Synparsuje się, ale wartość jest brzydka
"Kowalski & Syn"Kowalski & Synto jest podwójne escapowanie

Sam ampersand nie wysadzi bloku, bo JSON go nie wymaga uciekać. Prawdziwy problem zaczyna się przy cudzysłowie. Jeśli szablon zapisze " tam, gdzie powinien być \", po jednym przebiegu odescapowania zostaje ", a nie znak cudzysłowu. Blok nie domyka stringu i przestaje być JSON-em.

Skąd to się bierze w WordPressie? Prawie zawsze z podwójnego przetwarzania tej samej wartości. Treść przechodzi przez esc_html() przy zapisie, potem przez filtr motywu przy wyświetlaniu, a na końcu ląduje w polu JSON-LD, które i tak zrobiłoby własną ucieczkę. Każdy z tych kroków z osobna jest poprawny. Złożone razem produkują zapis, który przez lata działał tylko dlatego, że Google go za nas prostował.

#Jak sprawdzić własny korpus w pięć minut

Najważniejsza zasada brzmi: sprawdzasz zbudowany HTML, nie źródło szablonu. W źródle wszystko wygląda dobrze, bo escapowanie dokłada się dopiero na wyjściu. Jeśli masz statyczny build, skanujesz katalog wynikowy. Jeśli masz klasycznego WordPressa, pobierasz próbkę adresów przez wget albo curl i skanujesz to, co odpowiedział serwer.

Sama kontrola to kilkanaście linii. Wyciągnij każdy blok <script type="application/ld+json">, spróbuj go sparsować i osobno poszukaj wzorca podwójnej encji:

const RE = /<script[^>]*type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi;
let m;
while ((m = RE.exec(html))) {
  const body = m[1];
  if (/&amp;(quot|amp|lt|gt|#\d+);/.test(body)) report("podwójna encja", file);
  try { JSON.parse(body); } catch (e) { report("nie parsuje się: " + e.message, file); }
}

Dwa osobne testy, bo łapią różne rzeczy. JSON.parse wywróci się na uszkodzonym stringu, ale przepuści &amp;amp; w wartości, która nadal jest poprawnym JSON-em, tylko zawiera śmieć. Test na wzorzec encji łapie właśnie ten drugi przypadek: blok się parsuje, a w rich result widać &amp; zamiast znaku.

Trzeci test, który warto dopisać, to pojedyncze encje HTML w wartościach. One nie są błędem, ale po zmianie zostaną rozwinięte dokładnie raz, więc wynik może różnić się od tego, co widziałeś wcześniej. Lepiej wiedzieć, że je masz.

#Nasz pomiar: 68 055 bloków, zero błędów

Puściliśmy ten skan na własnym korpusie 30 sierpnia 2026, na świeżo zbudowanej wersji produkcyjnej.

metrykawynik
strony z co najmniej jednym blokiem JSON-LD15 742
bloków JSON-LD razem68 055
bloków, które nie parsują się jako JSON0
stron z podwójnie zaescapowaną encją0
stron z pojedynczą encją HTML w JSON-LD0

Zero we wszystkich trzech kategoriach. Nie piszemy tego jako chwały, tylko jako informacji o tym, co ten wynik znaczy i czego nie znaczy. Nasz stos generuje dane strukturalne z frontmattera przez komponenty Astro i wstawia je wzorcem set:html={JSON.stringify(...)}. JSON.stringify z definicji produkuje poprawny JSON, a set:html nie dokłada własnej ucieczki HTML. Innymi słowy: nie mieliśmy zera dlatego, że byliśmy ostrożni, tylko dlatego, że ten konkretny wzorzec nie ma jak wyprodukować podwójnego escapowania.

To jest ważniejsze niż sama liczba. Jeśli Twój stos składa JSON-LD przez konkatenację stringów w szablonie albo przez wtyczkę, która wkleja pole treści do gotowego kawałka JSON-a, ryzyko jest realne i wynik będzie inny. Zmierz swój, nie przepisuj naszego.

#Gdzie to pęka najczęściej w WordPressie

Z audytów, które robimy u klientów, wynikają trzy powtarzalne źródła.

Pierwsze to wtyczka SEO wypełniająca description z pola, które przeszło już przez wp_kses albo esc_attr. Najczęściej wysypuje się na apostrofie i cudzysłowie w polskich tekstach, bo tam takich znaków jest po prostu więcej niż w angielskich.

Drugie to ręczny blok JSON-LD wklejony do header.php albo do ustawień motywu, gdzie wartości wstawia się przez echo bez wp_json_encode. To najczęstszy wariant w motywach robionych na zamówienie kilka lat temu i najtrudniejszy do znalezienia, bo nie widać go w żadnym panelu wtyczki.

Trzecie to page builder, który zapisuje treść z encjami HTML już w bazie. Wtedy nawet poprawnie napisany generator JSON-LD dostaje na wejściu tekst z &amp; i uczciwie go zakoduje jeszcze raz.

Wspólny mianownik jest zawsze ten sam: wartość jest escapowana dwa razy, raz do HTML i raz do JSON, przez dwie różne warstwy, które o sobie nie wiedzą.

#Jak zapisać to poprawnie

Reguła jest jednoznaczna, bo mamy do niej standard. W wartości JSON uciekaj po jsonowemu, nie po htmlowemu.

W PHP oznacza to wp_json_encode() na całej strukturze, nigdy ręczne sklejanie stringów. W JavaScripcie JSON.stringify(). W szablonie Astro wzorzec, którego używamy u siebie:

<script type="application/ld+json" set:html={JSON.stringify(schema)} />

Jeśli naprawdę potrzebujesz znaku, który mógłby przedwcześnie zamknąć blok skryptu, użyj ucieczki uniwersalnej. & dla ampersanda i < dla znaku mniejszości są bezpieczne w każdym parserze JSON i nie wymagają żadnej wiedzy o HTML-u po stronie odbiorcy.

Czego nie robić: nie wstawiaj encji HTML do wartości JSON w nadziei, że ktoś je rozwinie. Przez lata rozwijał je Google. Od teraz rozwinie je dokładnie raz, a każdy inny konsument Twoich danych strukturalnych, od Binga po asystenta AI czytającego stronę, nie miał obowiązku robić tego nigdy.

#Jednorazowy audyt to za mało, zrób z tego bramkę

To jest ta część, którą najczęściej się pomija. Dane strukturalne nie są tekstem, który raz się napisze. Generuje je szablon, wtyczka albo integracja, i każda ich aktualizacja może wprowadzić escapowanie z powrotem. Audyt zrobiony dziś mówi tylko o dzisiejszym buildzie.

U siebie zamieniliśmy ten skan w bramkę uruchamianą po buildzie. Czyta katalog wynikowy, liczy bloki, próbuje sparsować każdy z nich i kończy się błędem tylko przy realnym problemie, czyli przy bloku, który się nie parsuje, albo przy podwójnej encji. Przy braku katalogu wynikowego kończy się zerem, żeby nie produkować fałszywego czerwonego w środowisku, w którym nikt jeszcze nie budował.

Trzy szczegóły, które decydują o tym, czy taka bramka jest coś warta. Po pierwsze musi czytać artefakt, nie źródło, bo źródło nie dowodzi niczego o escapowaniu. Po drugie musi liczyć bloki i pokazywać tę liczbę, żeby dało się zauważyć, że nagle spadła z 68 tysięcy do dwustu, bo integracja przestała je generować. Po trzecie musi rozróżniać błąd od informacji: pojedyncze encje HTML raportujemy, ale nie wywracamy na nich builda, bo to nie jest awaria, tylko coś, o czym trzeba wiedzieć.

#Co zrobić, gdy skan coś znajdzie

Skan daje listę plików, nie diagnozę. Zanim cokolwiek poprawisz, ustal, która warstwa produkuje ten zapis, bo naprawa w złym miejscu wróci przy najbliższej aktualizacji.

Weź jeden adres z listy i wyświetl surową odpowiedź serwera, na przykład curl -s ADRES | grep -A5 "application/ld+json". Popatrz, czy uszkodzona wartość pochodzi z tytułu wpisu, z opisu SEO, czy z pola własnego. To wskazuje warstwę szybciej niż czytanie kodu.

Dalej rozstrzygasz według źródła:

  1. Jeśli wartość pochodzi z wtyczki SEO, sprawdź, czy nie masz dwóch wtyczek generujących ten sam typ schema. Podwójny generator to częstsza przyczyna dziwnych wartości niż błąd w którymkolwiek z nich z osobna.
  2. Jeśli blok jest wklejony w motywie, przepisz go na wp_json_encode() na całej tablicy. Ręczne sklejanie stringów jest tu jedynym prawdziwym błędem i nie da się go załatać częściowo.
  3. Jeśli encje siedzą już w bazie, bo wstawił je page builder, nie naprawiaj ich w generatorze. Odkoduj wartość raz przed przekazaniem do enkodera JSON, na przykład przez html_entity_decode() z flagą dla cudzysłowów i jawnym UTF-8.

Klasyczny błąd wygląda tak:

echo '{"name":"' . esc_html( $title ) . '"}';

Poprawnie tak:

echo wp_json_encode( array( 'name' => $title ) );

Różnica nie polega na liczbie znaków, tylko na tym, kto odpowiada za ucieczkę. W pierwszym wariancie robi to funkcja HTML-owa w kontekście, który nie jest HTML-em. W drugim robi to enkoder JSON w kontekście JSON-a.

Po poprawce powtórz skan na nowym buildzie, a nie na starym artefakcie. To brzmi banalnie, ale połowa zgłoszeń „naprawiłem, a dalej jest błąd” to skan po starym katalogu wynikowym.

#Co realnie tracisz, jeśli to zignorujesz

Utrata schema nie boli od razu i to jest w tym najgorsze. Nie ma spadku pozycji z dnia na dzień, jest stopniowe znikanie rzeczy, które wyróżniały wynik: gwiazdek z ocen, danych o produkcie, listy FAQ, okruszków nawigacyjnych. Efekt zobaczysz w CTR, nie w pozycji, a CTR spada powoli i łatwo przypisać go czemu innemu.

Drugi odbiorca tych danych jest nowszy i mniej wybaczający. Silniki odpowiedzi czytają dane strukturalne, bo to najtańszy sposób, żeby ustalić, czym jest strona, bez interpretowania całej treści. U nas ruch agentów jest już mierzalny i nie jest marginalny: rzędu stu wizyt na dobę, z czego dwie trzecie przez nasz własny endpoint MCP. Te systemy nie mają żadnego powodu, żeby prostować cudze błędy escapowania. Google prostował je latami z uprzejmości wobec zastanego internetu. Nowy konsument Twoich danych nigdy takiego zwyczaju nie miał i nie nabierze.

Trzecia warstwa to Search Console, i tu trzeba uczciwie powiedzieć, czego się nie dowiesz. Raporty wyników z elementami rozszerzonymi pokażą spadek liczby prawidłowych elementów, ale nie powiedzą „blok nie sparsował się z powodu podwójnej encji”. Zobaczysz, że encji ubyło, i będziesz musiał sam dojść dlaczego. Dlatego skan po własnej stronie jest wart tych kilku minut: daje przyczynę, a nie tylko objaw.

#Czego o tej zmianie nie wiemy i co robić mimo to

Nie znamy daty wdrożenia. Nie wiemy, czy zmiana dotyczy w równym stopniu wszystkich typów schema, ani czy Search Console w ogóle zaraportuje utraconą encję, czy po prostu przestanie pokazywać rich result. Nie ma zaktualizowanej dokumentacji, do której można odesłać klienta. To są realne luki i lepiej powiedzieć to wprost, niż udawać, że komunikat na LinkedIn ma rangę specyfikacji.

Mimo tych luk decyzja operacyjna jest prosta i nie zależy od żadnej z brakujących informacji. Poprawny JSON był poprawny również wtedy, gdy Google prostował błędy za nas. Sprawdź swój zbudowany HTML, napraw to, co się nie parsuje, zamień encje HTML w wartościach na ucieczki JSON i wpnij ten test w proces, żeby nie wracał. Jeśli wynik wyjdzie zerowy, jak u nas, to też jest wynik: wiesz, że Twój generator nie ma jak wyprodukować tego błędu, i możesz przestać się nad tym zastanawiać przy każdej aktualizacji wtyczki.

Największe ryzyko w tej historii nie leży w samej zmianie, tylko w tym, że jest cicha. Żaden alert nie przyjdzie. Rich result po prostu przestanie się pojawiać, a w raporcie za trzy miesiące zobaczysz spadek widoczności bez oczywistej przyczyny. Pięć minut skanu dzisiaj jest tańsze niż to dochodzenie.

Następny krok

Przekuj artykuł w realne wdrożenie

Pod tym wpisem dokładam linki, które domykają intencję użytkownika i prowadzą dalej w strukturze serwisu.

Chcesz wdrożyć ten temat na swojej stronie?

Jeśli zależy Ci na widoczności w Google i systemach AI, mogę przygotować architekturę treści, FAQ, schema i linkowanie pod GEO, AEO i SEO.

Powiązany klaster

Sprawdź inne usługi WordPress i bazę wiedzy

Wzmocnij swój biznes dzięki profesjonalnemu wsparciu technicznemu w kluczowych obszarach ekosystemu WordPress.

FAQ do artykułu

Często zadawane pytania

Najważniejsze odpowiedzi, które pomagają wdrożyć temat w praktyce.

SEO-readyGEO-readyAEO-ready5 Q&A
Co dokładnie zmienił Google w ekstrakcji JSON-LD?#
Google stosuje teraz jeden przebieg odescapowania HTML zamiast wcześniejszego prostowania podwójnie zaescapowanej treści. W komunikacie brzmi to tak: „we changed our JSON-LD extraction and are now only applying a single pass of HTML unescaping”. Podwójnie zaescapowane encje, na przykład zapisane jako &amp; zamiast &, nie są już rozwijane.
Czy moja strona na tym ucierpi?#
Tylko wtedy, gdy w bloku JSON-LD faktycznie masz podwójne escapowanie albo blok, który nie parsuje się jako JSON. Sprawdzasz to na zbudowanym HTML, nie w źródle szablonu. My przeskanowaliśmy 68 055 bloków na 15 742 stronach i znaleźliśmy zero przypadków, ale to wynik konkretnego stosu, a nie gwarancja dla każdego.
Jak zapisać znak ampersand albo znak specjalny poprawnie w JSON-LD?#
Zgodnie z RFC 8259, czyli standardowym escapowaniem JSON, albo ucieczką uniwersalną w postaci \u0026. Nie encją HTML i na pewno nie encją zaescapowaną drugi raz. Gary Illyes z Google odesłał wprost do RFC 8259 jako definicji poprawnego escapowania.
Od kiedy zmiana obowiązuje?#
Google nie podał daty wdrożenia. Komunikat pojawił się na LinkedIn, a relacja Search Engine Roundtable jest z 21 sierpnia 2026. Nie ma też linku do zaktualizowanej dokumentacji, więc traktuj to jako stan zgłoszony przez Google, nie jako wpis w dokumentacji.
Czy wystarczy jednorazowy audyt?#
Nie. Dane strukturalne generuje szablon, wtyczka albo integracja, a każda ich aktualizacja może wprowadzić escapowanie z powrotem. Sensowniej wpiąć parsowanie każdego bloku JSON-LD w bramkę uruchamianą po buildzie, żeby regresja padała, zamiast po cichu kasować schema.

Potrzebujesz FAQ dopasowanego do branży i rynku? Przygotujemy wersję pod Twoje cele biznesowe.

Porozmawiajmy

Polecane artykuły

Polityka site reputation abuse w EOG od 30 sierpnia 2026

Od 30 sierpnia 2026 Google dzieli skutek manual action w polityce site reputation według lokalizacji wyszukującego. Poza EOG degradacja nadal dotyczy dotkniętej części. W EOG skutek kary nie obowiązuje; sekcja może rankować niezależnie. Dlaczego parasite SEO nie wraca.

Czyszczenie treści AI-slop

Diagnostyka YMYL dla WordPress: fałszywe statystyki, zmyślone cytowania, zduplikowane strony AI, błędne daty i wymyślone biogramy zespołu, zanim zniszczą zaufanie, zgodność lub cytowania w AI.