Микроразметка Schema.org на Тильде: что есть, а что руками
Просьба «поставьте микроразметку» звучит как настройка, которую забыли включить. Настройки такой нет. На четырёх снятых страницах Тильды — образовательной, магазинной, Zero Block и с формой, вместе 1.9 МБ — ровно ноль блоков JSON-LD и шестьдесят разметок картинки. Ни FAQPage, ни HowTo, ни Product там не появится ни при каких заполненных полях. Ниже — что именно Тильда генерирует, из чего, и как добавить своё, не поломав её собственное.
Короткий ответ
Тильда размечает картинки и больше почти ничего. На четырёх снятых страницах — 60
разметок ImageObject, ноль блоков JSON-LD и ни одного Product на 27 карточках
товара. FAQPage, HowTo, Article и Product добавляются руками, JSON-LD в
<head> страницы. Тильдовскую разметку это не задевает: у них разные слои.
Что Тильда ставит сама: посчитано, а не пересказано
Четыре страницы, снятые целиком вместе со скриптами и стилями: образовательный курс, магазин, Zero Block и страница с формой. Вместе 1.9 МБ разметки. Что в них нашлось:
| Страница | application/ld+json | itemtype | Какие itemprop |
|---|---|---|---|
| Zero Block | 0 | 59 × ImageObject | image 59, caption 10, name 6 |
| Образовательная | 0 | 1 × NewsArticle | description 1, image 14 |
| С формой | 0 | 1 × ImageObject | image 1 |
| Магазин | 0 | — | — |
Три вывода читаются прямо из таблицы.
Первый: JSON-LD Тильда не пишет никогда. Ни один из 53 её скриптов не вставляет
<script type="application/ld+json">. Всё, что она размечает, — микроразметка
атрибутами прямо в HTML: itemscope, itemtype, itemprop. Для поисковика это
равноценные форматы, но для вас это значит, что ваш JSON-LD с её разметкой не
столкнётся: они живут в разных местах.
Второй: ImageObject — почти вся её разметка. Появляется он у блоков галерей и
слайдеров, вокруг каждой картинки:
<div itemscope itemtype="http://schema.org/ImageObject">
<meta itemprop="image" content="https://static.tildacdn.com/…/photo.jpg">
<meta itemprop="name" content="Подпись из редактора">
<meta itemprop="caption" content="Описание из редактора">
</div>
Причём генерируют его два разных скрипта и в двух разных схемах: скрипт блоков
страницы пишет http://schema.org/ImageObject, а скрипт каталога товаров —
https://schema.org/ImageObject. Парсерам всё равно, оба варианта валидны, но
поправить у себя один из них «для единообразия» не выйдет: их пишет не ваш код.
Третий: тип всей страницы задаётся на <body>, и это единственная точка входа.
На образовательной странице стоит:
<body itemscope itemtype="http://schema.org/NewsArticle">
а itemprop="description" — на контейнере #allrecords, то есть описанием статьи
объявлено всё содержимое страницы. И на этом всё: headline, datePublished,
author — обязательные для Article поля — не выставлены ни одного раза.
Разметка есть, а данных в ней нет.
Чего Тильда не размечает: магазин
Это самое частое ожидание и самое неверное. В снятой странице магазина 27 карточек
товара, и в них — ноль атрибутов микроразметки. Ни Product, ни Offer, ни
price, ни availability.
Причина видна в коде каталога: карточки на странице появляются не сразу. Скрипт
отправляет запрос на https://store.tildaapi.com/api/getproductslist/ и рисует
разметку из ответа. Разметка, вставленная в <head> руками, к этому моменту уже
отдана поисковику, а товаров в ней нет.
Отсюда правило, которое экономит день работы: статичный JSON-LD для товаров писать нельзя. Либо разметка собирается тем же скриптом после ответа магазина — и тогда её увидит только тот краулер, который выполняет JavaScript, — либо цены и наличие в разметке разъедутся с настоящими. Второе хуже, чем отсутствие разметки: за расхождение цены в разметке и на странице Google снимает расширенный сниппет целиком.
Как добавить FAQPage: единственный случай, где всё просто
FAQPage — та разметка, которую просят чаще всего, и единственная из четырёх, где
данные уже лежат в HTML и не меняются после загрузки. Блок с вопросами (T585, T668,
любой аккордеон) статичен, значит разметку можно написать текстом.
Настройки страницы → «Ещё» → «HTML-код для вставки внутрь HEAD»:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Сколько идёт доставка?",
"acceptedAnswer": {
"@type": "Answer",
"text": "По Москве — на следующий день, по России — от трёх дней."
}
},
{
"@type": "Question",
"name": "Можно вернуть товар?",
"acceptedAnswer": {
"@type": "Answer",
"text": "В течение 14 дней, если сохранена упаковка."
}
}
]
}
</script>
Три правила, из-за нарушения которых разметку отклоняют:
- Текст вопроса и ответа должен совпадать с видимым на странице. Не пересказ — тот же текст. Разметка, описывающая то, чего человек не видит, — это ровно то, за что бывает ручная санкция.
FAQPage— на страницу, а не на блок. ДвухFAQPageна одной странице быть не должно; если аккордеонов два, вопросы из обоих идут в одинmainEntity.- Ответ — plain text или простой HTML. Ссылки и
<p>внутриtextдопустимы, кавычки внутри JSON — экранируются, иначе весь блок молча не распарсится.
Проверять — валидатором Schema.org и «Проверкой структурированных данных» Яндекса. Оба берут адрес опубликованной страницы; в режиме редактирования проверять бессмысленно, там другая разметка.
HowTo и Article: что изменилось и что осталось
HowTo в 2023 году перестала давать расширенный сниппет в Google — осталась
на мобильных в ограниченном виде и как обычный сигнал о структуре. Ставить её ради
картинки в выдаче больше нет смысла; ставить, чтобы описать структуру инструкции
для языковых моделей и Яндекса, — по-прежнему есть.
Article — случай интереснее, потому что на образовательных страницах Тильда его
уже объявила на <body>, но не заполнила. Если вы добавите свой JSON-LD с
@type: "Article", на странице окажутся две сущности сразу: её пустая
микроразметка и ваша заполненная. Ошибкой это не считается, но выбирать между ними
будет поисковик, а не вы.
Надёжнее — дописать недостающее тем же способом, каким размечена сама Тильда: атрибутами. Заголовок статьи в блоке T005:
<!-- В блок T123 рядом с заголовком, если тип NewsArticle уже стоит на body -->
<script>
var h1 = document.querySelector('.t005 h1, .t-title');
if (h1 && document.body.hasAttribute('itemtype')) {
h1.setAttribute('itemprop', 'headline');
}
</script>
Это работает, но у такого пути есть цена: атрибут появляется после выполнения
скрипта. Краулер, который JavaScript не выполняет, увидит разметку без заголовка —
то есть ровно то, что было. Поэтому для Article честнее написать свой JSON-LD
целиком, со всеми полями, и не пытаться дополнять чужую пустую разметку.
Как это устроено у нас: рабочий пример на 300 строк
Разметка витрины, на которой вы читаете эту статью, собирается в одном файле —
src/data/schema.ts. Он открыт, и он же ответ на вопрос «а как правильно»:
- Один узел объявляется один раз и получает
@id.Organization— этоhttps://modkod.ru/#organization, и во всех остальных схемах на него стоит ссылка{"@id": "https://modkod.ru/#organization"}, а не копия объекта. Иначе поисковик видит десять разных организаций с одинаковым названием. - Узел, на который ссылаются, обязан быть на этой же странице. Ссылка на
@id, которого на странице нет, не собирается ни во что — она просто игнорируется. Это самая частая и самая незаметная ошибка: разметка валидна, а связей нет. - Чего нет в данных — того нет в разметке. Поле без значения не печатается
вообще. Пустая строка в
priceили выдуманныйratingValue— это не «разметка почти готова», это неверные данные о вашем бизнесе, поданные машиночитаемо. FAQPageберётся из тех же вопросов, которые напечатаны на странице. Не из отдельного списка «для разметки» — из одного массива, который рисует и видимый аккордеон, и разметку. Разъехаться им нечем.
Последний пункт — единственный способ соблюдать правило «разметка совпадает с видимым» не силой воли, а устройством.
Кто это делает и сколько это стоит
Вопрос из чата звучал так: «Кто может настроить микроразметку? Сколько будет стоить?» Честный ответ зависит от того, что просят.
FAQPage на статичный аккордеон — вставка кода на 20 минут. Это делается по
инструкции выше, платить за это не нужно.
Article на блог, LocalBusiness на контакты, BreadcrumbList на разделы —
несколько часов: данные надо собрать со страниц, @id связать, разметку проверить
в двух валидаторах.
Product для магазина — уже разработка, а не настройка: разметка собирается
скриптом после ответа store.tildaapi.com, следит за сменой варианта товара и не
врёт про наличие. Это работа под задачу, и оценивается она от
конкретного магазина.
Полезно понимать, чего разметка не делает: она не поднимает позиции сама по себе. Она даёт поисковику право показать расширенный сниппет и даёт языковой модели структуру, по которой она разбирает ответ. Первое видно в выдаче, второе — в том, процитируют вас или страницу конкурента.
Проверка за пять минут на своей странице
В консоли на опубликованной странице:
// 1. Сколько на странице JSON-LD и какие это типы. До ваших правок — ноль.
[...document.querySelectorAll('script[type="application/ld+json"]')]
.map((s) => JSON.parse(s.textContent)['@type']);
// 2. Что размечено атрибутами и в каких схемах.
[...document.querySelectorAll('[itemtype]')].map((el) => el.getAttribute('itemtype'));
// 3. Какие свойства заполнены. Для NewsArticle без headline — это пустая разметка.
[...document.querySelectorAll('[itemprop]')].map((el) => el.getAttribute('itemprop'));
Если вторая строка вернула десятки ImageObject, а третья — только image и
caption, у вас типовая страница Тильды и разметки на ней, по сути, нет. Если
первая строка вернула ваш FAQPage, а валидатор Яндекса его не видит, — почти
всегда незакрытая кавычка внутри text: JSON не распарсился, и об этом никто не
сообщил.
Готовые моды библиотеки микроразметку не ставят и не ломают — они работают со своими классами и в чужие атрибуты не пишут. Что они делают, видно в каталоге.