Przejdź do głównej zawartości

Dane strukturalne Schema.org

Polski for WooCommerce nie drukuje własnych danych strukturalnych. WooCommerce sam wystawia na stronie produktu graf JSON-LD Product, a wtyczka dokłada do niego pola przez filtr woocommerce_structured_data_product.

To świadomy wybór: dwa grafy Product na jednej stronie to błąd duplikacji, a wyszukiwarki i tak potraktują je jak jeden. Wszystko poniżej jest więc uzupełnieniem tego, co wystawia WooCommerce, a nigdy zamiennikiem.

Źródło Pola
WooCommerce name, description, image, sku, offers z ceną, walutą, dostępnością i stanem, aggregateRating i review
Polski for WooCommerce brand, manufacturer, gtin8 / gtin12 / gtin13 / gtin14, additionalProperty z ceną jednostkową, shippingDetails, nutrition
Polski for WooCommerce, w ofercie priceValidUntil oraz najniższa cena z 30 dni (Omnibus) jako priceSpecification

Jeśli na stronie produktu nie ma danych strukturalnych WooCommerce, nie ma do czego dokładać i wtyczka nie doda nic. Ma to znaczenie, gdy wtyczka SEO zastępuje graf WooCommerce własnym, zobacz Wtyczki SEO poniżej.

Dodatki z pierwszego bloku są zabezpieczone dwoma przełącznikami: moduł Dane strukturalne (Schema.org) musi być włączony, a wewnątrz niego przełącznik Włącz integrację danych strukturalnych. Wyłączenie któregokolwiek zostawia graf WooCommerce nietknięty i kompletny.

Ustawienie Klucz opcji Domyślnie Odpowiada za
Włącz integrację danych strukturalnych polski_seo[schema_enabled] włączone Wszystko z tabeli poniżej
Dołącz markę polski_seo[schema_brand] włączone brand
Dołącz producenta polski_seo[schema_manufacturer] włączone manufacturer
Dołącz kody kreskowe (GTIN) polski_seo[schema_gtin] włączone gtin8 do gtin14
Dołącz cenę jednostkową polski_seo[schema_unit_price] włączone additionalProperty

Czas dostawy i wartości odżywcze nie mają własnego przełącznika. Pojawiają się wtedy, gdy produkt ma te dane, i znikają, gdy ich nie ma.

Dwa dodatki do oferty działają osobno. priceValidUntil zapisywane jest niezależnie od modułu, bo oferta bez tego pola traci prawo do wyników rozszerzonych i nie ma powodu, dla którego sklep miałby tego chcieć. Specyfikacja ceny Omnibus idzie za modułem Omnibus i pojawia się tylko wtedy, gdy produkt jest faktycznie w promocji.

{
"brand": { "@type": "Brand", "name": "MojaMarka" },
"manufacturer": {
"@type": "Organization",
"name": "Producent XYZ Sp. z o.o.",
"contactPoint": {
"@type": "ContactPoint",
"contactType": "product safety",
"description": "[email protected], +48 22 000 00 00"
}
}
}

brand to pierwsza marka znaleziona dla produktu. manufacturer zaczyna się od nazwy producenta z panelu produktu, a nazwa producenta GPSR wpisana przy produkcie zastępuje ją i dokłada kontakt GPSR jako contactPoint typu product safety. Adres nie jest publikowany, a treść kontaktu drukowana jest dokładnie tak, jak ją wpisano.

Kod kreskowy z panelu produktu publikowany jest pod kluczem pasującym do jego długości: 8 cyfr to gtin8, 12 to gtin12, 13 to gtin13, 14 to gtin14. Każda inna długość trafia do zwykłego gtin, co jest poprawne w Schema.org, ale mówi Google mniej.

Schema.org nie ma własności na cenę jednostkową, więc liczba jedzie w additionalProperty:

{
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "Cena jednostkowa",
"value": "8.90 / 100 g"
}
]
}

Gdy produkt ma ustalony czas dostawy, dokładany jest blok OfferShippingDetails:

{
"shippingDetails": {
"@type": "OfferShippingDetails",
"deliveryTime": {
"@type": "ShippingDeliveryTime",
"handlingTime": { "@type": "QuantitativeValue", "minValue": 0, "maxValue": 1, "unitCode": "DAY" },
"transitTime": { "@type": "QuantitativeValue", "minValue": 1, "maxValue": 3, "unitCode": "DAY" }
},
"shippingDestination": { "@type": "DefinedRegion", "addressCountry": "PL" }
}
}

Dwa ograniczenia warto znać, zanim się na tym oprzesz. Czas przygotowania jest na sztywno ustawiony na 0 do 1 dnia, a nie czytany z ustawień, natomiast górna granica czasu transportu brana jest z cyfr w Twoim tekście o czasie dostawy, a przy ich braku wynosi 5 dni. Czas dostawy zapisany jako „2 do 3 dni roboczych” daje więc górną granicę 23. Jeśli ta liczba ma dla Ciebie znaczenie, trzymaj w tekście jedną liczbę.

Krajem docelowym jest Polska.

Produkty z danymi odżywczymi z modułu żywnościowego dostają obiekt NutritionInformation:

Zapisany składnik Pole Schema.org
Wartość energetyczna (kcal) calories
Tłuszcz fatContent
w tym kwasy nasycone saturatedFatContent
Węglowodany carbohydrateContent
w tym cukry sugarContent
Białko proteinContent
Błonnik fiberContent
Sól sodiumContent, po przeliczeniu

Ostatni wiersz to ten, który warto przeczytać dwa razy. Załącznik XV rozporządzenia 1169/2011 podaje sól, a Schema.org ma wyłącznie sodiumContent i nie jest to ta sama liczba: sól to sód pomnożony przez 2,5. Wartość jest dzielona przez 2,5 przed publikacją, więc produkt z etykietą 2,5 g soli publikuje 1 g sodu. Do wersji 1.36.7 liczba szła dalej bez zmiany, przez co każdy produkt spożywczy publikował się jako dwa i pół raza bardziej słony niż mówi jego własna etykieta.

Wartość energetyczna w kJ nie ma odpowiednika w Schema.org i nie jest publikowana. Nadal pojawia się w tabeli na stronie produktu, gdzie wymaga jej rozporządzenie.

{
"offers": [
{
"priceValidUntil": "2026-12-31",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"priceType": "https://schema.org/MinimumPrice",
"name": "Najniższa cena z 30 dni",
"price": "79.00",
"priceCurrency": "PLN"
}
}
]
}

priceValidUntil używa daty końca promocji, gdy produkt ją ma, a w przeciwnym razie daty za rok. Pole zapisywane jest tylko wtedy, gdy WooCommerce zostawiło je puste.

priceSpecification niesie najniższą cenę z poprzednich 30 dni wymaganą przez dyrektywę Omnibus. To ta sama liczba, którą widzi klient pod ceną, opublikowana w formie, którą wyszukiwarka albo asystent może zacytować, i pojawia się tylko wtedy, gdy produkt jest w promocji, a moduł Omnibus jest włączony.

Dokładane pola trzymane są per produkt w transiencie polski_schema_<id> przez 12 godzin, a transient kasowany jest przy każdym zapisie produktu.

Jedna konsekwencja: zmiana powyższych przełączników nie czyści bufora. Istniejący produkt zachowuje poprzednie pola nawet przez 12 godzin albo do momentu zapisania. Zapisz produkt, żeby zobaczyć zmianę ustawień od razu.

Wtyczka nie udostępnia własnych filtrów dla danych strukturalnych. Użyj filtra WooCommerce, z priorytetem wyższym niż 10, żeby Twoje wywołanie wykonało się po wtyczce:

add_filter( 'woocommerce_structured_data_product', function ( array $markup, WC_Product $product ): array {
$markup['award'] = 'Produkt Roku 2025';
if ( isset( $markup['offers'][0] ) ) {
$markup['offers'][0]['warranty'] = [
'@type' => 'WarrantyPromise',
'durationOfWarranty' => [
'@type' => 'QuantitativeValue',
'value' => 24,
'unitCode' => 'MON',
],
];
}
return $markup;
}, 20, 2 );

Żeby usunąć pole dodane przez wtyczkę, skasuj je w tym samym wywołaniu. Żeby wtyczka przestała dokładać cokolwiek, użyj przełączników, a nie kodu.

Nie ma tu żadnego wykrywania ani zachowań pod konkretną wtyczkę. Wszystko zależy od tego, co dana wtyczka SEO robi z grafem WooCommerce:

  • Zostawia dane strukturalne WooCommerce na miejscu. Dodatki pojawiają się tak, jak opisano.
  • Zastępuje dane strukturalne WooCommerce własnym grafem. Nie dokłada się nic, bo filtr nigdy się nie wykonuje. Kilka wtyczek SEO ma przełącznik dokładnie na to; włącz tam z powrotem dane strukturalne WooCommerce albo przenieś potrzebne pola do grafu tamtej wtyczki. To, która z nich je usuwa i czy robi to domyślnie, zmienia się między ich wydaniami, więc sprawdź źródło własnej strony, a nie listę.

Jeśli widzisz w źródle strony dwa bloki Product, ten drugi nie pochodzi z tej wtyczki. Szukaj we wtyczce SEO albo w motywie.

Wtyczka nie loguje niczego o danych strukturalnych, więc pusty debug.log niczego nie dowodzi w żadną stronę. Czytaj źródło strony albo użyj powyższych dwóch narzędzi.

Nie ma żadnych dokładanych pól. Sprawdź, czy na stronie są własne dane strukturalne WooCommerce. Jeśli nie ma bloku Product, filtr nie miał na czym zadziałać.

Pole nadal nie widać, chociaż je wypełniłem. Produkt musi mieć dane, odpowiedni przełącznik musi być włączony, a potem produkt trzeba zapisać, żeby wyczyścić 12-godzinny bufor.

Brak ocen. aggregateRating pochodzi z WooCommerce, a nie z tej wtyczki, i wymaga co najmniej jednej opinii z oceną gwiazdkową.

Google nie pokazuje wyników rozszerzonych. Wyniki rozszerzone idą za ponowną indeksacją, która trwa tygodniami. Najpierw zwaliduj, potem czekaj.

Zgłaszanie problemów: github.com/wppoland/polski/issues

Ta strona ma wyłącznie charakter informacyjny i nie stanowi porady prawnej. Przed wdrożeniem skonsultuj się z prawnikiem. Polski for WooCommerce jest oprogramowaniem open source (GPLv2) dostarczanym bez gwarancji.