Senior Frontend Architect, 10+ років досвіду побудови production-проєктів на Next.js. Contentful Certified Professional (2024). Спеціалізація: React Server Components, headless eCommerce, інженерія Core Web Vitals.
Структуровані дані Schema.org у форматі JSON-LD - водночас найменш використовувана SEO-техніка (більшість сайтів віддають або нуль розмітки, або зламану) і найсильніша одинична зміна, яку можна зробити: правильно зібрана Product-схема з AggregateRating приносить зірочки у видачі без жодного рядка нового контенту. У цьому гайді я розбираю три речі: модель графа сутностей Schema.org - як зв'язування через @id перетворює розрізнені блоки JSON-LD на представлення знань, яким Google і мовні моделі справді можуть користуватися; архітектуру вставки в Next.js App Router - що generateMetadata() може і чого не може, чому вставка через серверний компонент правильна і який XSS-вектор у dangerouslySetInnerHTML більшість реалізацій лишає відкритим; і картину з rich results на 2026 рік - які типи ще працюють, що прибрали (HowTo, вересень 2023), що обмежили (FAQPage, серпень 2023) і чому «невинагороджувану» розмітку все одно варто тримати заради цитування в AI.
Чому Schema.org - це граф сутностей, а не словник тегів?
Бо він описує сутності та зв'язки між ними, а не сторінку, на якій вони опинилися. Schema.org - це спільний словник для опису сутностей та їхніх зв'язків, розрахований на машини, які будують представлення знань, а не лише на парсер rich results у Google. Концептуальна помилка, з якої народжуються марні впровадження, - ставитися до нього як до словника тегів, тобто до списку міток @type, що прикрашають вміст сторінки. Різниця в підході дає різні архітектурні рішення.
Schema.org визначає три базові категорії: Things (будь-яка сутність, що існує у світі: Person, Product, Article, Organization), Actions (події, які можна підтвердити: Purchase, SearchAction, ReviewAction) і DataTypes (текст, число, дата, URL). Кожен тип схеми - підклас однієї з них. BlogPosting успадковується від Article → CreativeWork → Thing. Цей ланцюг визначає, які властивості припустимі: BlogPosting отримує всі властивості Article і CreativeWork, включно з headline, author, datePublished та image.
Граф сутностей від набору JSON-блоків відрізняє зв'язування через @id. Кожна сутність, на яку посилаються інші, повинна мати властивість @id - глобально унікальний URI, що є її ідентифікатором. BlogPosting із властивістю "author": { "@type": "Person", "name": "Yevhen Samkov" } описує анонімну сутність Person. Той самий BlogPosting із властивістю "author": { "@type": "Person", "@id": "https://samcheek.com/about#person", "name": "Yevhen Samkov" } посилається на відому сутність із постійним ідентифікатором - ту саму, що описана схемою Person на сторінці About, у властивості author у WebSite та у схемах Review. Коли Google бачить той самий URI в @id на різних сторінках і в різних властивостях, він накопичує свідчення про цю сутність. Саме так особисті бренди й компанії отримують картки Knowledge Panel: через послідовні перехресні описи сутності, а не через розмітку однієї сторінки.
- Патерн @graph: Кілька пов'язаних сутностей однієї сторінки можна об'єднати в один блок JSON-LD під ключем
"@graph": [...]. Це чистіше, ніж кілька тегів<script type="application/ld+json">, і робить зв'язки між сутностями явними. Приклад: сторінка поста об'єднуєWebPage,BlogPosting,BreadcrumbListіPerson(автора) в один блок @graph. Google обробляє @graph як єдине ціле, що допомагає йому вивести відношення між сутностями. - sameAs як механізм перехресних посилань: Властивість
sameAsзв'язує сутність з її представленнями в інших авторитетних джерелах."sameAs": ["https://www.linkedin.com/in/...", "https://twitter.com/...", "https://www.wikidata.org/wiki/Q..."]каже Google, що всі ці зовнішні профілі описують одну й ту саму сутність. Кожне посилання вsameAs- сигнал підтвердження: що більше авторитетних джерел підтверджують сутність, то впевненіший Google у її представленні в Knowledge Graph. - @context як оголошення словника: У кожному блоці JSON-LD обов'язково має бути
"@context": "https://schema.org". Без нього імена типів і властивостей нічого не означають - це довільні рядки.@contextзіставляє їх із визначеннями словника Schema.org. Блок JSON-LD без@contextне дає взагалі жодної цінності й не проходить валідацію.
JSON-LD vs Microdata vs RDFa: який формат обрати у 2026?
Усі три формати виражають ті самі структуровані дані Schema.org. Різниця у технічних компромісах, і вона пояснює, чому у 2026 році варто використовувати лише JSON-LD.
- Microdata (атрибути HTML5): Додає атрибути
itemscope,itemtypeтаitempropпрямо в HTML-елементи.<div itemscope itemtype="https://schema.org/Product"><span itemprop="name">Blue Shirt</span></div>. Проблеми: (1) жорстко прив'язує розмітку даних до структури DOM - будь-який рефакторинг верстки може непомітно зламати схему; (2) не дає описати те, що на сторінці не відмальовано -dateModifiedстатті не потрапить у Microdata, якщо його не показано користувачу; (3) погано читається на код-рев'ю. Microdata домінував у 2012–2016 роках, до того як Google остаточно став на бік JSON-LD. - RDFa (атрибути HTML від W3C): Схожий на Microdata, але з просторами імен, успадкованими з XML:
<div vocab="https://schema.org/" typeof="Product"><span property="name">Blue Shirt</span></div>. Трохи виразніший за Microdata, але з тією ж прив'язкою до подання. У веброзробці трапляється рідко, зате поширений в академічних публікаціях і державних даних. - JSON-LD (JavaScript Object Notation for Linked Data): Структуровані дані в блоці
<script type="application/ld+json">, повністю відокремлені від HTML-розмітки сторінки. Плюси: (1) незалежність від подання - описати можна будь-які дані, а не лише відмальовані; (2) стійкість до рефакторингу - зміни верстки на розмітку не впливають; (3) генерується програмно з тих самих об'єктів даних, якими рендериться сторінка; (4) рекомендований Google формат з 2016 року і єдиний підтримуваний для деяких типів rich results. Важливо:<script type="application/ld+json">браузер не виконує як JavaScript - MIME-тип каже йому, що це дані, а не код. Але парситься він як JSON, а не як JS, тому JS-коментарі та висячі коми ламають розбір.
Де вставляти JSON-LD у Next.js App Router: Server Component чи generateMetadata?
В App Router є два механізми вставки вмісту в <head>: функція generateMetadata() і прямий рендер серверного компонента. Розуміння, що за що відповідає, визначає всю архітектуру розмітки.
- Чого
generateMetadata()НЕ вміє: ТипMetadata, який вона повертає, керує<title>,<meta>,<link rel>і тегами соціальних карток. Довільні теги<script>він не підтримує. ПолівstructuredDataабоjsonLdу типіMetadataнемає. Вставити JSON-LD черезgenerateMetadata()неможливо. - Вставка
<script>у серверному компоненті (правильний шлях): JSON-LD вставляється прямо в JSX серверного компонента:<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />. Це відмальовується в<head>або<body>сторінки залежно від місця розміщення. Клієнтський JavaScript не бере участі: тег уже є у вихідному серверному HTML. - Патерн компонента
<StructuredData>: Тонка обгортка (components/Seo/StructuredData.tsx), яка інкапсулює вставку: приймає пропdata(типізований якRecord<string, unknown>) і рендерить тег<script>. Так на всіх сторінках з'являється єдиний канонічний спосіб вставки, і стає легко перевірити, у яких сторінок розмітка є і які типи вони віддають. - XSS через dangerouslySetInnerHTML - вразливість, яку пропускають:
JSON.stringify(data)може видати рядок, що містить</script>, якщо це сполучення потрапило в будь-яке поле даних. Назва товару на кшталт'Example</script><script>alert(1)</script>'змусить браузер вважати тег JSON-LD закритим на</script>і виконати впроваджений скрипт. Лікування:JSON.stringify(data).replace(/</g, '\\u003c'). Екрановані юнікод-послідовності - валідний JSON, тому парсери структурованих даних отримують правильний символ<, а браузер ніколи не бачить буквального</script>усередині блоку. Так само робить і сам Google, серіалізуючи свої структуровані дані.
Де що розміщувати: Сутності рівня сайту (WebSite, Organization/Person, SearchAction) живуть в app/layout.tsx - вони є на кожній сторінці й описують сайт як сутність, а не вміст конкретної сторінки. Сутності рівня сторінки (Article, Product, BreadcrumbList, FAQPage) генеруються в page.tsx відповідного маршруту з даних цієї сторінки. Розділення повторює ієрархію сутностей: сутність сайту стабільна і присутня всюди, сутності сторінок динамічні й прив'язані до маршруту.
Яка site-level схема потрібна кожному Next.js-сайту (WebSite, Organization, Person)?
Блок схеми рівня сайту в app/layout.tsx задає фундамент графа сутностей для всього проєкту. Для сайту особистого бренду або незалежного архітектора правильний тип - Person, а не Organization: останній для компаній зі співробітниками. Для агенції чи SaaS-продукту вірний саме Organization.
- Схема WebSite (потрібна для Sitelinks Searchbox):
{ "@type": "WebSite", "@id": "https://example.com#website", "url": "https://example.com", "name": "Site Name", "potentialAction": { "@type": "SearchAction", "target": { "@type": "EntryPoint", "urlTemplate": "https://example.com/search?q={search_term_string}" }, "query-input": "required name=search_term_string" } }. СамеpotentialAction.SearchActionвмикає Sitelinks Searchbox - поле пошуку під посиланням сайту в брендовій видачі. Працює лише якщо у вас справді є пошуковий ендпоінт. - Схема Person (особистий бренд): Ключові властивості:
name,url(сторінка профілю),image(портрет, Google бере його в Knowledge Panel),jobTitle,description,sameAs(посилання на соцпрофілі),address(PostalAddressзaddressLocalityтаaddressCountry),knowsAbout(масив тем, допомагає AI-системам зрозуміти експертизу),worksForдля співробітників абоhasOccupationдля фрилансерів і консультантів. URI в@id(https://example.com/about#person) - постійний ідентифікатор сутності, на який посилаються всі схеми статей і відгуків. - Схема ProfessionalService: Для сервісного бізнесу
ProfessionalService(підкласLocalBusiness) додаєserviceTypeі дозволяєhasOfferCatalog. Google вимагає для локальних rich results:name,address(PostalAddress),telephone,openingHours. Для повністю віддаленого бізнесу замість фізичної адреси підійдеareaServedз країною або масивом об'єктів GeoShape - але фізична адреса помітно підсилює локальні сигнали. - Повнота sameAs: Кожен унікальний авторитетний зовнішній профіль у
sameAs- сигнал підтвердження сутності. Мінімум для портфоліо розробника: LinkedIn і GitHub. Наполегливо варто додати: Twitter/X, Crunchbase (якщо є) і Wikidata (якщо застосовно). Google звіряє їх між собою, набираючи впевненість в особі та галузі експертизи.
Як зв'язати BlogPosting з єдиною сутністю автора в усіх постах?
Розмітку Article впроваджують найчастіше і найчастіше ламають. Причина в тому, що обов'язкові для rich results поля в Google конкретніші, ніж описує більшість туторіалів, а неправильна прив'язка автора - найчастіший спосіб усе зіпсувати.
- Ієрархія типів: Для статей блогу правильний тип -
BlogPosting. Ланцюг успадкування:BlogPosting→Article→CreativeWork→Thing.NewsArticleберіть лише для журналістики визнаних новинних видань: до цього типу Google застосовує інші вимоги щодо E-E-A-T.Article- загальний тип,BlogPostingсигналізує саме редакційний блоговий формат. - Обов'язкові поля для rich results Google (2026):
headline(рядок, до 110 символів для нормального відображення),image(ImageObject або URL, мінімум 1200×630 пікселів для каруселі),datePublished(ISO 8601:"2026-03-18"або"2026-03-18T10:00:00Z", а не людиночитана дата),author(Person або Organization зnameі, що критично, з@id, який вказує на сутність Person цього сайту, заради успадкування E-E-A-T). Пропуск будь-якого з них дає warnings у Rich Results Test, а вони гасять право на rich result. - dateModified важливий для свіжості: Інструкції Google для асесорів прямо велять враховувати свіжість контенту.
dateModifiedу розмітці дає машиночитаний сигнал свіжості окремо від HTTP-заголовкаLast-Modified. Для вічнозеленого технічного матеріалу оновлюйтеdateModified, коли переписано істотний розділ, а не коли виправлено одруківку. - Прив'язка автора через @id (ланцюг E-E-A-T):
"author": { "@type": "Person", "@id": "https://samcheek.com/about#person", "name": "Yevhen Samkov", "url": "https://samcheek.com/about" }. Це зв'язує авторство статті з описаною на сайті сутністю Person, у якої єknowsAbout,sameAsіdescription. Google іде за посиланням@idі враховує заявлену експертизу людини, оцінюючи E-E-A-T статті. Анонімний автор (лише ім'я, без@id) дає сигнал помітно слабший.
Що потрібно Product-схемі, щоб потрапити в merchant listings і rich results?
Product - найконверсійніший тип розмітки: зібраний правильно, він дає у видачі зірочки рейтингу, ціну і статус наявності, а це піднімає CTR на 15–30% (Google, документація з Product Markup, 2025). Як це влаштовано в headless-вітрині на Shopify, розібрано в гайді з архітектури headless Shopify; тут - вимоги самої схеми.
- Обов'язкові поля для Product rich results:
name,image(хоча б один URL або ImageObject),offers(сутність Offer). В Offer мають бути:price(рядок, не число:"29.99"),priceCurrency(ISO 4217:"USD"),availability("https://schema.org/InStock",OutOfStockабоPreOrder),url(канонічний URL товару). Без повного набору Rich Results Test видає помилки й знімає право на rich result. - AggregateRating (зірочки у видачі):
"aggregateRating": { "@type": "AggregateRating", "ratingValue": "4.8", "bestRating": "5", "worstRating": "1", "ratingCount": 247 }. ПолеratingCountGoogle вимагає обов'язково - самогоreviewCountзамало. Можна вказати обидва:ratingCount- кількість оцінок, включно з тими, що без тексту,reviewCount- кількість написаних відгуків. Зірочки Google не покаже, докиratingCountне буде хоча б 1 і доки оцінки не виявляться перевірно справжніми: за накручені відгуки прилітають ручні санкції. - Merchant listings (Google Shopping): Товари з валідною розміткою
Product+Offerпотрапляють у безкоштовні merchant listings у вкладці Shopping - окремо від платних PLA. Умови: властивістьOffer.sellerвказує продавця ({ "@type": "Organization", "name": "Store Name" }), а сторінка має бути карткою одного товару, а не категорією. Це безкоштовний канал, який більшість headless-впроваджень просто не підключає. - Варіанти, канонічні URL і схема: У товару з 50 варіантами кольору й розміру кожен URL варіанта (
/products/shirt?variant=123) має нести схемуProductзі своєю ціною, наявністю і SKU, але з властивістюurl, що вказує на канонічний URL базового товару. Якщо варіанти окремо не індексуються (канонікал веде на базовий товар), лишіть одну схему Product на базовому URL, аoffersзробіть масивом сутностей Offer за кількістю доступних варіантів.
Чи корисна FAQPage-схема після обмеження Google від серпня 2023?
З 2019 по 2023 рік FAQPage була однією з найвіддачливіших розміток для комерційних сайтів: вона давала акордеон під основним результатом видачі й різко розширювала зайняте місце. У серпні 2023 року Google лишив право на цей rich result лише державним і медичним сайтам. Це не означає, що FAQPage марна. Це означає, що її цінність переїхала з видачі Google у цитованість в AI-системах.
- Як саме обмежили у 2023: Зміна Rich Results у серпні 2023 прибрала акордеони FAQPage для «неавторитетних» сайтів, тобто для комерційних, блогів і більшості видань. Саму розмітку застарілою не оголошували, на відміну від HowTo: вона просто перестала вмикати візуальне розширення для цих типів сайтів. Державні портали охорони здоров'я й офіційні держсайти право зберегли.
- Цінність для цитування в AI (чому FAQPage варто лишити): Мовні моделі й AI-пошук (Google AI Overviews, Perplexity, ChatGPT з браузингом) витягують структурований контент зі сторінок, щоб процитувати його у згенерованій зведенці. Структура
Question+acceptedAnswer.textдає заздалегідь розмічений формат питання-відповідь, який AI-системи витягують точніше, ніж еквівалентну прозу. УacceptedAnswer.textмає бути повна самодостатня відповідь, а не «докладніше за посиланням»: збираючи цитати, AI-системи за посиланнями не ходять. Це і є основний принцип Generative Engine Optimization (GEO) - структурувати контент під витягування машиною, а не лише під візуальні фічі видачі. - Що робити комерційному сайту: Наявну розмітку FAQPage лишіть: вона дає цінність для цитування в моделях, а Bing досі показує частину FAQ-подібних результатів і комерційним сайтам. Видаляти не треба. Але й додавати FAQPage заради rich results у Google уже не варто - цей потяг пішов. Натомість варто проєктувати блоки питань із повноцінними
acceptedAnswer.textзаради машинної цитованості, а не заради входжень ключів. Докладніший розбір оптимізації під AI-пошук - в послузі технічного SEO. - Як це виглядає:
{ "@type": "FAQPage", "mainEntity": [{ "@type": "Question", "name": "Що таке headless Shopify?", "acceptedAnswer": { "@type": "Answer", "text": "Headless Shopify відокремлює комерційний бекенд Shopify від шару відмальовування, дозволяючи кастомній вітрині на Next.js чи іншому фреймворку отримувати дані Shopify через Storefront API." } }] }.Question.name- текст питання,acceptedAnswer.text- повна відповідь.
Як BreadcrumbList керує відображенням URL у Google SERP?
- Структура схеми:
{ "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com" }, { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog" }, { "@type": "ListItem", "position": 3, "name": "Article Title" }] }. Останньому елементу ланцюгаitemне потрібен - це поточна сторінка. Значенняpositionмають іти послідовними цілими числами починаючи з 1. - Що змінюється у видачі: BreadcrumbList змінює те, як Google показує URL сторінки: замість
https://example.com/blog/long-post-slug-2026з'являється людиночитаний шляхexample.com › Blog › Article Title. Це піднімає CTR, бо знімає в користувача, що сканує видачу, тривогу від незрозумілої адреси. - Збіг із видимими хлібними крихтами: Вимоги Google до структурованих даних зобов'язують, щоб BreadcrumbList збігався з видимою навігацією на сторінці. Схема, яка заявляє ієрархію, відмінну від відмальованих крихт, вважається оманливою розміткою, а за це прилітають ручні санкції. Генеруйте схему і компонент навігації з одного джерела даних - тоді розбіжність неможлива.
Які поля Service-схеми обов'язкові для сервісного бізнесу у 2026?
- Тип Service:
{ "@type": "Service", "name": "Next.js Performance Optimization", "serviceType": "Frontend Architecture Consulting", "provider": { "@type": "Person", "@id": "https://samcheek.com/about#person" }, "areaServed": "Worldwide", "url": "https://samcheek.com/services/performance-optimization" }. Властивістьproviderзв'язує послугу з сутністю Person через@id, вибудовуючи ланцюг сайт → людина → послуга. Google використовує його для локальних сервісних rich results (якщо є адреса) і для записів «послуги, які надає» у графі знань. - hasOfferCatalog: Групує кілька послуг:
"hasOfferCatalog": { "@type": "OfferCatalog", "name": "Frontend Architecture Services", "itemListElement": [ { "@type": "Offer", "itemOffered": { "@type": "Service", "name": "Headless eCommerce Architecture" } }, ... ] }. Особливо корисно агенціям, де Google треба зрозуміти широту пропозиції. - BreadcrumbList на сторінці послуги: У кожної сторінки послуги має бути свій ланцюг:
Home → Services → [назва послуги]. Це закріплює архітектуру сайту в структурованих даних і доповнює ієрархію XML-карти.
Які типи Schema.org Google оголосив застарілими, і на що переходити?
Google періодично припиняє підтримку rich results для окремих типів. Впроваджувати застарілі типи сенсу немає: вони додають вагу сторінці й не дають нічого у видачі, а вже впроваджені треба знайти й прибрати або замінити.
- HowTo - прибрано у вересні 2023: Google припинив підтримку rich results для HowTo у вересні 2023 року, тим самим пакетом, що й обмеження FAQPage. Раніше HowTo давав у видачі покрокові блоки з нумерацією та картинками. Усю розмітку HowTo на комерційних сайтах варто видалити: користі у видачі нуль, а попередження в Rich Results Test вона створює.
- Часта помилка: немає @context: У кожному блоці JSON-LD обов'язково має бути
"@context": "https://schema.org". Без нього парсер Google вважає імена типів і властивостей довільними рядками без сенсу. Rich Results Test відрапортує «No structured data found», навіть якщо JSON у решті валідний. - Часта помилка: регістр у @type: Типи Schema.org пишуться в PascalCase:
Product,BlogPosting,BreadcrumbList, а неproduct,blog-posting,breadcrumb-list. Властивості - в camelCase:datePublished,ratingValue,offerCount. Типи в нижньому регістрі частина парсерів мовчки не пропускає, а Google рапортує «unknown type». - Часта помилка: формат datePublished: Лише ISO 8601. Валідно:
"2026-03-18","2026-03-18T10:00:00Z","2026-03-18T10:00:00+02:00". Невалідно:"18 березня 2026","18.03.2026". Rich Results Test іноді ковтає хибний формат без помилки, але конвеєр індексації Google мовчки його відкидає, і rich result для статті гаситься. - Часта помилка: ціна числом: В Offer у Schema.org
priceмусить бути рядком:"price": "29.99", а не"price": 29.99. Це особливість специфікації, що суперечить звичкам JSON. Причина в тому, що Schema.org має вміти представляти ціни, які не виражаються точно числом з рухомою комою IEEE 754 - у деяких валютах потрібна недесяткова арифметика. Валідатори Google і Bing приймають число з попередженням, але специфікація вимагає рядок. - Часта помилка: відносні URL в
urlабоitem: Усі URL-властивості JSON-LD (url,item,@id,imageу рядковому вигляді) мають бути абсолютними."/blog/post"невалідний,"https://example.com/blog/post"- вірний. Відносні адреси валять валідацію і позбавляють уражену сутність права на rich result. - Вектор впровадження через </script>: Як розібрано вище,
JSON.stringify(data)без екранування відкриває XSS, якщо в дані потрапило сполучення</script>. Завжди санітизуйте:JSON.stringify(data).replace(/</g, '\\u003c'). Особливо критично для користувацького контенту - назв товарів, текстів відгуків, відповідей FAQ із CMS, - який потрапляє в розмітку перед рендером.
Як валідувати JSON-LD до викату в прод?
- Google Rich Results Test (search.google.com/test/rich-results): Перевіряє URL або сирий HTML на право отримати rich result. Повертає знайдені типи схем, статус обов'язкових полів, попередження та помилки. «No errors» означає, що схема валідна; «Eligible for rich results» - що сторінка претендує на розширення у видачі. Валідна схема не гарантує rich result: за Google завжди лишається редакційне рішення про якість сторінки й різноманіття видачі.
- Schema.org Validator (validator.schema.org): Перевіряє відповідність специфікації Schema.org, а не вимогам Google. Суворіший за Rich Results Test: ловить невідповідності типів і властивостей та невідомі імена властивостей. Користуйтеся обома: Rich Results Test - для права на rich result у Google, Schema.org Validator - для відповідності специфікації.
- Google Search Console, звіт «Покращення»: Коли розмітка проіндексована, розділ «Покращення» показує знайдені типи rich results, кількість елементів, помилки й попередження загалом по сайту. Це єдиний інструмент, який показує здоров'я розмітки в продакшен-масштабі, а не за одним URL. Підпишіться на листи GSC про помилки структурованих даних: вони приходять протягом 1–2 днів після індексації нових сторінок із проблемами.
Висновок
Розмітка, зібрана як граф сутностей - зв'язування через @id, послідовні посилання на ті самі сутності, перехресні sameAs, повний набір обов'язкових полів, - накопичує ефект із часом так, як підхід «поставити галочки за типами» не вміє. Rich result - це негайна виплата. Довга цінність у тому, що представлення сутності в Knowledge Graph перетворює сайт і його автора на цитоване джерело для AI Overviews, зведенок Perplexity та іншого пошуку на мовних моделях.
Архітектура серверних компонентів у Next.js App Router робить вставку JSON-LD чистою і передбачуваною: схема генерується на сервері з тих самих об'єктів даних, якими рендериться сторінка, і клієнтський JavaScript у цьому не бере участі. Патерн компонента <StructuredData> і безпечна серіалізація (replace(/</g, '\\u003c')) - дві деталі, на яких спотикається більшість реалізацій. Живий приклад того, як пронести схему й SEO-метадані крізь зміну платформи без втрат, є в розборі міграції WordPress на Next.js-CMS, де збережено метадані Yoast і право на rich results.
Аудит структурованих даних, впровадження або повне технічне SEO-рев'ю - послуга технічного SEO і схеми | кейси | обговорити проєкт.
Часті питання
- Що обрати: @graph чи кілька тегів <script type="application/ld+json">? Обидва варіанти валідні й обробляються Google однаково. @graph чистіший, коли між сутностями сторінки є явні зв'язки - наприклад, властивість
authorу BlogPosting посилається на Person, описаного в тому ж блоці. Кілька тегів<script>простіші, коли типи генеруються незалежно: скажімо, BreadcrumbList і Article збираються з різних джерел у різних компонентах. - Чи впливає розмітка на ранжування напряму? Ні. Google послідовно каже, що структуровані дані - не фактор ранжування. Це сигнал права на rich results, інструмент розведення сутностей у Knowledge Graph і підсилювач цитованості в AI. Непряма користь для позицій іде від зростання CTR завдяки rich results і від підсилення E-E-A-T через зв'язування сутностей.
- Як розмічати посторінкову навігацію (/blog?page=2)? У кожної сторінки пагінації має бути свій BreadcrumbList. У схемі
WebPageвластивістьurlмає збігатися з канонічним URL саме цієї сторінки. Лістинги статей розмічайте схемоюItemListзі статтями цієї сторінки. СхемуWebSiteможна лишити на першій сторінці; на наступних її дублювати не потрібно. - Чи безпечно генерувати JSON-LD на сервері з даних CMS? Так, із застереженням про XSS: серіалізуйте лише через
JSON.stringify().replace(/</g, '\\u003c')і ніколи не склеюйте JSON-LD рядками. У даних CMS - назвах товарів, описах, текстах відгуків - регулярно трапляються символи, здатні зламати розбір JSON-LD або, у гіршому разі, впровадити теги скриптів. - Що буде, якщо прибрати раніше проіндексований тип схеми? Google втратить право на rich result для цієї сторінки під час наступного обходу. У GSC ненадовго може підрости число «Помилок», доки раніше проіндексовані покращення інвалідуються. На органічні позиції сторінки це напряму не впливає - втрачається лише розширення у видачі.
Джерела
- Schema.org. «Full Hierarchy»
- Google. «Introduction to Structured Data»
- Google. «Rich Results Types»
- Google. «Article structured data»
- Google. «Product structured data»
- Google. «FAQPage update (серпень 2023)»
- W3C. «JSON-LD 1.1 Specification»
- Google. «Rich Results Test»
- Schema.org Validator
- Barnett, M. «XSS via JSON-LD in Next.js»
- Google. «How structured data works»
