Представим динамический сайт с редакционной системой.
В 10:00 редактор публикует новую статью:
https://example.ru/expert/webhook-securityСайт уже сделал всё необходимое:
HTTP 200
TITLE
H1
self-canonical
Article JSON-LD
sitemap.xml
внутренняя ссылка из /expertДля пользователя страница появилась мгновенно.
Но поисковая система работает независимо.
Она должна:
узнать о новом URL
↓
запланировать обход
↓
получить страницу
↓
проанализировать её
↓
принять решение об индексацииЕсли просто ждать очередного обхода сайта, между публикацией и обнаружением изменения может пройти некоторое время.
Для динамического сайта, где регулярно появляются:
новые статьи;
обновлённые услуги;
изменённые карточки;
новые кейсы;
удалённые страницы;возникает логичный вопрос:
Можно ли самим сообщать поисковой системе, что конкретный URL только что изменился?
Да.
Для этого существует протокол IndexNow.
Яндекс официально поддерживает IndexNow и позволяет автоматически уведомлять его о новых, изменённых и удалённых страницах, не ожидая, пока робот самостоятельно обнаружит изменение при очередном обходе. При этом Яндекс отдельно подчёркивает: отправка URL через IndexNow не гарантирует его включение в индекс.
Это принципиально важно.
IndexNow — не:
«добавить страницу в Яндекс»а:
«сообщить Яндексу:
этот URL изменился,
обратите на него внимание»И если воспринимать протокол именно так, он очень хорошо встраивается в современную редакционную систему.
Что решает IndexNow
У поискового робота традиционно есть несколько способов обнаружить изменение сайта.
Например:
внутренняя ссылка;
sitemap.xml;
повторный crawl известной страницы;
ручная отправка на переобход;
другие сигналы.IndexNow добавляет ещё один канал:
Сайт
↓
сам сообщает:
URL изменился
↓
поисковая система получает сигналТо есть модель меняется с полностью pull-подхода:
поисковик когда-нибудь
сам проверит страницуна комбинацию:
crawler
+
активное уведомление сайта.Яндекс рекомендует сочетать подходящие способы уведомления об изменениях — Sitemap, переобход, IndexNow и другие доступные механизмы, а не рассматривать их как взаимоисключающие технологии.
IndexNow не заменяет Sitemap
Это одна из самых важных практических границ.
Sitemap отвечает на вопрос:
Какие канонические публичные страницы составляют наш сайт?
IndexNow:
Какие конкретные страницы только что добавились, изменились или были удалены?
Например Sitemap содержит:
/
/prices
/services
/expert/article-a
/expert/article-b
/expert/article-cи отражает текущее состояние сайта.
В 14:37 изменяется:
/expert/article-bНет смысла заново сообщать поисковику:
вот весь сайт.Можно отправить:
/expert/article-bчерез IndexNow.
Яндекс прямо рекомендует через IndexNow передавать новые, изменённые или удалённые страницы, а не использовать протокол для периодической массовой отправки всех URL сайта. Для полного представления структуры сайта остаётся Sitemap.
Получается полезное разделение:
Sitemap
=
состояние сайта
IndexNow
=
события изменения сайтаЭто почти snapshot и event
Если смотреть на архитектуру как разработчик:
sitemap.xmlпохож на snapshot:
Вот актуальный набор наших индексируемых страниц.
А:
IndexNowна event:
URL X только что изменился.
Это хорошая модель для динамического продукта.
Когда отправлять URL через IndexNow
Первый очевидный случай — новая публикация.
Статья переходит:
DRAFT
↓
PUBLISHEDи впервые становится:
public;
HTTP 200;
indexable;
self-canonical.После успешной публикации можно сформировать событие:
INDEXNOW_SUBMIT
url=https://example.ru/expert/article
reason=publishedВторой случай — существенное изменение страницы
Например статья уже существует, но редактор:
добавил большой новый раздел;
обновил устаревшие данные;
изменил основной текст;
существенно переработал структуру;
изменил важные SEO-данные.Теперь есть смысл сообщить:
Эта известная вам страница изменилась.
Но не нужно отправлять IndexNow после каждого UPDATE в базе
Например произошло:
view_count += 1Публичный текст статьи не изменился существенно.
Или:
admin_last_opened_at = now()Вообще не связано с публичной страницей.
Или:
internal_note = ...Пользователь этого даже не видит.
Если IndexNow привязан просто к:
row.updated_at changedсистема начнёт генерировать огромное количество бессмысленных уведомлений.
Лучше иметь понятие public change
Например:
content_revisionили:
public_updated_atизменяется только когда модифицирована публичная версия документа.
Тогда правило становится:
public content changed
→ IndexNow eventа не:
любой SQL UPDATE
→ IndexNow.Третий случай — удаление страницы
Допустим материал:
/expert/old-apiудалён без замены.
Теперь сервер отвечает:
410 Goneили:
404 Not FoundIndexNow можно использовать и для сообщения о таком изменении.
Яндекс прямо разрешает передавать через IndexNow страницы, которые теперь возвращают 404 или 410.
То есть событие:
PUBLISHED
↓
DELETEDтоже может автоматически создавать IndexNow notification.
Четвёртый случай — URL переехал
Было:
/expert/old-urlСтало:
/expert/new-urlСтарый URL:
301 → /expert/new-urlНовый:
200 OKВ такой ситуации полезно сообщить об изменении соответствующих адресов.
Яндекс допускает отправку через IndexNow URL, которые теперь возвращают 301 или 302, то есть протокол можно использовать и для уведомления об изменившейся redirect-семантике страницы.
При этом сам SEO-lifecycle всё равно должен быть правильным:
old
→ 301 new
new
→ 200
→ self-canonical
sitemap
→ new onlyIndexNow это дополняет, а не заменяет.
Что не стоит отправлять
Представим страницу:
/admin/articlesОна изменилась.
Это не означает, что её нужно отправлять Яндексу.
Внутренний search:
/search?q=crmсгенерировал новый результат.
Тоже не обязательно поисковое событие.
Появилась временная preview-страница:
/preview/article/1842Если она не предназначена для organic search, IndexNow ей не нужен.
Поэтому перед созданием notification полезно сначала проверить:
Это публичный URL?и уже затем:
Какое именно SEO-событие произошло?IndexNow должен идти после публикации, а не перед ней
Это важная инженерная деталь.
Плохой процесс:
начали публиковать статью
↓
IndexNow отправлен
↓
запись в БД не сохранилась
↓
URL возвращает 404Мы сообщили поисковой системе об URL, который ещё не существует корректно.
Лучше так
Publish transaction
↓
COMMIT
↓
public URL available
↓
SEO validation
↓
IndexNow jobТо есть внешний notification является следствием успешно завершённой публикации.
Ещё лучше проверить страницу перед отправкой
Например после publication:
GET public URLи убедиться:
HTTP 200;
не noindex;
canonical корректный.После этого:
IndexNow.Это особенно полезно для собственной CMS
Если статья:
PUBLISHEDно из-за ошибки маршрутизации реально:
404,IndexNow лишь быстрее сообщит поисковику о сломанной странице.
Сам протокол не проверяет качество вашего релиза за вас.
Ключ подтверждения
Нельзя позволить любому человеку сообщать Яндексу:
На example.ru изменились вот эти страницы.
Поэтому IndexNow использует ключ подтверждения управления сайтом.
Общая схема:
генерируем key
↓
размещаем key-файл
на сайте
↓
передаём key
в IndexNow request
↓
поисковая система
проверяет файлЯндекс требует ключ длиной от 8 до 128 символов; допустимы латинские буквы, цифры и дефис. Файл должен содержать ключ и быть доступен поисковой системе. Яндекс рекомендует размещать его в корне сайта.
Как выглядит key-файл
Допустим ключ:
ExampleKey-8F42A7Тогда удобно разместить:
https://example.ru/ExampleKey-8F42A7.txtСодержимое:
ExampleKey-8F42A7Без HTML.
Без JSON.
Просто текст.
Почему корень удобнее
Если key-файл находится в корне host:
https://example.ru/<key>.txtон может использоваться для URL этого host.
Если разместить его глубже:
/catalog/<key>.txtобласть применения ключа ограничивается соответствующим путем.
И официальная документация IndexNow, и Яндекс рекомендуют корневой вариант как наиболее простой.
Отдельно про поддомены
Если архитектура:
example.ru
blog.example.ru
shop.example.ruнельзя без проверки предполагать, что ownership автоматически распространяется одинаково на всё.
Яндекс рекомендует использовать отдельный ключ для каждого поддомена.
Для обычного проекта это ещё один аргумент не плодить subdomains без необходимости.
Отправка одного URL
Для одного адреса Яндекс поддерживает GET-запрос:
GET https://yandex.com/indexnow
?url=https%3A%2F%2Fexample.ru%2Fexpert%2Farticle
&key=ExampleKey-8F42A7Если key-файл расположен нестандартно, можно дополнительно передать:
keyLocation.Текущий официальный endpoint Яндекса для IndexNow — https://yandex.com/indexnow.
Но для редакционной системы удобнее POST
Представим одновременно опубликовано:
7 статей;
2 кейса;
1 новая услуга.Делать десять отдельных запросов необязательно.
IndexNow поддерживает batch submission.
Яндекс принимает JSON:
{
"host": "example.ru",
"key": "ExampleKey-8F42A7",
"urlList": [
"https://example.ru/expert/article-a",
"https://example.ru/expert/article-b",
"https://example.ru/services/crm"
]
}через:
POST https://yandex.com/indexnow
Content-Type: application/jsonВ одном запросе Яндекс разрешает передать до 10 000 URL. Такой же лимит указан в официальном протоколе IndexNow.
Но возможность отправить 10 000 URL не означает, что это нужно делать постоянно
Представим сайт содержит:
350 статей.Редактор изменил одну.
Плохая автоматизация:
статья изменена
↓
отправляем все 350 URL.Лучше:
изменена одна
↓
отправляем одну.IndexNow — change notification.
Не ежедневный полный экспорт Sitemap.
Какой ответ считать успешным
При нормальной подтверждённой отправке Яндекс возвращает:
200 OKЭто означает:
URL принят сервисом.
Но не:
URL уже проиндексирован.
И официальный протокол IndexNow отдельно подчёркивает: HTTP 200 подтверждает получение URL поисковой системой, а не включение страницы в индекс.
При первом использовании можно получить 202
Яндекс использует:
202 Acceptedкогда новый key ещё ожидает проверки.
Документация рекомендует убедиться, что файл размещён правильно, немного подождать и отправить несколько других адресов; переход ответа к 200 означает, что проверка ключа завершилась и URL принимаются обычным образом.
Это важно для собственной админ-панели.
Не нужно интерпретировать:
202как:
индексация выполнена.Лучше сохранить:
pendingVerification.Полезная внутренняя модель состояния
Например:
PENDING
SENT
ACCEPTED
PENDING_KEY_VERIFICATION
RETRY
FAILEDИ хранить ответ отдельно от состояния страницы
Статья:
PUBLISHEDне должна становиться:
UNPUBLISHEDтолько потому, что IndexNow временно ответил ошибкой.
Это независимые процессы.
Хорошая таблица IndexNow jobs
Например:
indexnow_jobsс полями:
id
url
reason
created_at
attempts
next_attempt_at
last_http_status
last_error
accepted_atи, если нужно:
content_revisionПочему полезно хранить reason
Например:
PUBLISHED
CONTENT_UPDATED
DELETED
REDIRECTEDЧерез месяц можно понять:
Почему этот URL вообще был отправлен?
Почему useful content_revision
Допустим статья быстро редактируется:
revision 41
↓
42
↓
43За десять секунд.
Не обязательно создавать три внешних запроса.
Можно оставить одну pending job:
URL
latest_revision=43.Это называется coalescing
То есть:
UPDATE
UPDATE
UPDATEсливаются в:
один notification
последнего состояния.Для редакционных систем это особенно полезно.
Не отправляйте URL на каждое нажатие «Сохранить»
Редактор может:
исправить заголовок;
сохранить;
исправить абзац;
сохранить;
добавить ссылку;
сохранить.Если каждый autosave вызывает IndexNow:
10 изменений
→ 10 запросов.Никакой пользы.
Лучше привязать уведомление к публикационному событию
Например:
Save draft
→ ничего.
Publish
→ send.
Edit published article
→ mark public revision changed.
Publish changes
→ send.Если CMS сохраняет изменения сразу публично, можно использовать debounce.
Например:
после изменения
подождать небольшой период
↓
если новых изменений нет
↓
отправить latest revision.Но не нужно придумывать частоту отправки случайно
У Яндекса нет фиксированного общего лимита на число IndexNow-запросов, но используются алгоритмы защиты от чрезмерных отправок. Один и тот же URL Яндекс не рекомендует посылать слишком часто; если повтор действительно нужен, в документации указан ориентир не чаще примерно 10-минутного интервала. При слишком большом числе запросов возможен 429 Too Many Requests.
Следовательно, архитектура:
каждую секунду
повторять URL,
пока он не появится в поискенеправильна.
IndexNow не нужно использовать как polling
Плохо:
не нашли URL в Яндексе
↓
send IndexNow
↓
через минуту ещё раз
↓
ещё
↓
ещёПротокол сообщает факт изменения страницы.
Он не является командой:
Попробуй индексировать ещё раз, пока не получится.
Если страница не появляется в поиске
Нужно диагностировать:
HTTP;
robots;
noindex;
canonical;
контент;
дубли;
SSR/rendering;
качество документа.Не увеличивать число IndexNow-запросов.
Потому что IndexNow не отменяет обычные правила SEO
Представим:
/article-aотправлен успешно.
IndexNow:
200 OK.Но сама страница:
<meta
name="robots"
content="noindex"
>IndexNow не должен «победить» noindex.
Или canonical указывает на другую страницу
/article-a
canonical → /article-b.IndexNow сообщил:
A изменился.
После обхода поисковик всё равно видит:
Сам сайт считает основным B.
Или страница возвращает soft 404
HTTP 200но основной контент:
Материал не найден.
IndexNow лишь ускоряет доставку информации о текущем состоянии URL.
Он не делает плохую страницу хорошей.
Поэтому правильная последовательность важнее скорости
Для новой статьи:
Create
↓
Publish
↓
HTTP 200
↓
Indexability check
↓
Canonical check
↓
Sitemap update
↓
Internal listing update
↓
IndexNowНе обязательно выполнять всё синхронно
Например публикация статьи не должна ждать:
ответа Яндекса.Иначе внешний сервис становится частью критического пользовательского transaction.
Представим Яндекс временно недоступен
Редактор нажимает:
Опубликовать.Если код делает:
save article
↓
send IndexNow
↓
timeout
↓
transaction failedстатья почему-то не публикуется из-за внешней SEO-интеграции.
Это плохая зависимость.
Лучше использовать outbox/job
Publication transaction
│
├── article = PUBLISHED
│
├── SEO metadata committed
│
└── IndexNow job created
↓
COMMIT
↓
article available
↓
worker
↓
IndexNowТеперь:
Яндекс доступен
→ job completed.Если:
timeout
→ retry later.Статья всё равно опубликована.
Это особенно хорошо сочетается с PostgreSQL job queue
Например:
indexnow_jobsworker забирает через:
FOR UPDATE SKIP LOCKEDнеобработанные задачи.
Система получает:
retry;
failed state;
наблюдаемость;
durability.Сам IndexNow при этом остаётся внешней интеграцией, которая не может остановить редакционную систему.
Какие ошибки стоит retry
Например:
network timeout;
5xx;
429.могут быть временными.
Но 403 — другой класс
Яндекс возвращает:
403 Invalid keyесли ключ невозможно загрузить либо он не соответствует запросу.
Бесконечный retry:
403
↓
ещё 403
↓
ещё 403не решит проблему.
Нужна проверка конфигурации.
То же с 422
Например:
Invalid URL;
Invalid key location;
неподходящий key;
слишком короткий key;
слишком длинный key.Это configuration/data error, а не временный outage.
Значит retry policy должна различать ошибки
Условно:
200
→ DONE
202
→ PENDING_KEY_VERIFICATION
429
→ RETRY_WITH_BACKOFF
5xx/network
→ RETRY
400/403/422
→ FAILED_CONFIGURATIONЭто гораздо профессиональнее:
if status != 200:
retry foreverExponential backoff
Если внешний сервис временно недоступен, можно использовать:
1 min
5 min
15 min
1 h
...с ограничением числа attempts.
Не:
100 запросов в секунду.У IndexNow job должен быть terminal failed state
Например после нескольких безуспешных попыток:
FAILED.Администратор видит:
URL:
/expert/article
Reason:
CONTENT_UPDATED
Attempts:
7
Last response:
403 Invalid keyТеперь понятно, что проблема требует человека.
Не скрывайте сбой IndexNow
Плохая реализация:
try {
await sendIndexNow(url);
} catch {
// ignore
}Система выглядит исправной.
Но уже полгода ничего не отправляет.
Нужна наблюдаемость
Минимально полезные метрики:
indexnow_jobs_created
indexnow_requests_total
indexnow_accepted_total
indexnow_pending_verification_total
indexnow_failed_total
indexnow_retry_totalИ:
oldest_pending_job_age.Особенно полезно показывать состояние в админ-панели
Например у статьи:
Опубликовано:
09.10.2026 16:14
Sitemap:
✓
IndexNow:
200 OK
09.10.2026 16:14
Причина:
PublishedИли:
IndexNow:
⚠ 202 Pending verificationIndexNow:
✗ 403 Invalid keyТеперь IndexNow — наблюдаемая часть редакционной системы.
Не скрытый fetch() где-то после сохранения статьи.
Но не путайте статус IndexNow со статусом индексирования
Это очень важно для интерфейса.
Плохо показывать:
Проиндексировано:
✓только потому, что Яндекс ответил:
200.Это фактически неверно.
Лучше:
IndexNow:
URL принят Яндексомили:
Уведомление отправлено.Потому что решение о crawling и indexing принимается отдельно. Яндекс прямо пишет, что IndexNow не гарантирует индексацию переданного URL.
Значит в админке можно разделить
Publication:
PUBLISHED
Sitemap:
INCLUDED
IndexNow:
ACCEPTED
Search indexing:
отдельная информация,
если она вообще доступнаЭто профессиональная семантика
Не обещать системе больше, чем она реально сообщает.
IndexNow при массовой публикации
Допустим была миграция редакционной системы.
Опубликовано:
800 новых страниц.Не обязательно создавать:
800 GET requests.Можно сформировать batch.
Но batch лучше строить из событий
Например worker каждые несколько секунд собирает:
до N pending URLи отправляет:
{
"host": "example.ru",
"key": "...",
"urlList": [
"...",
"...",
"..."
]
}Очень большой batch не всегда нужен
Разрешено до:
10 000 URL.Но технический максимум не означает оптимальный размер конкретной queue.
Можно использовать:
50;
100;
500в зависимости от нагрузки и удобства retry.
Почему маленькие batch иногда удобнее
Представим один batch:
10 000 URLs.возвращает:
422.Теперь нужно выяснить, какой URL или параметр испортил request.
При меньших партиях диагностика проще.
Можно валидировать URL до постановки job
Например:
protocol = https/http;
host = production host;
URL RFC3986-compatible;
no preview token;
no localhost.Яндекс требует корректные URL и возвращает 422 при неподходящих данных.
Не отправляйте localhost
Кажется очевидным.
Но генератор может взять:
PUBLIC_BASE_URLиз неправильного environment:
http://localhost:4173и начать создавать IndexNow jobs.
Это production configuration bug.
Поэтому startup preflight полезен
В production:
PUBLIC_BASE_URL
=
https://example.ruи:
IndexNow host
=
тот же ожидаемый host.Если нет:
application startup failsили SEO subsystem явно переходит в failed configuration.
IndexNow key тоже проверяем при deployment
Полезный smoke test:
GET https://example.ru/<key>.txtОжидаем:
HTTP 200
Content-Type: text/plain
body = expected keyНе превращайте IndexNow key в application route, который иногда ломается
Например:
/<key>.txtгенерируется через:
React;
database;
authentication middleware.Слишком много зависимостей.
Лучше key-файл отдаётся максимально просто:
Nginx/static fileили простым серверным endpoint без авторизации.
Но ключ не должен попадать в случайные места
Не нужно:
console.log(INDEXNOW_KEY)или отправлять его в client-side JavaScript.
IndexNow вызывается:
с backend.Не из браузера пользователя.
Почему не frontend
Если browser после публикации делает:
fetch('https://yandex.com/indexnow?...&key=...')ключ становится доступен клиенту.
Кроме того, notification начинает зависеть от:
закрыл ли редактор вкладку;
сработал ли браузер;
CORS;
сетевого соединения пользователя.Это серверная интеграция.
IndexNow — часть backend publication pipeline
Хорошая архитектура:
Admin
↓
Publish
↓
Backend
↓
DB commit
↓
Outbox/job
↓
IndexNow worker
↓
YandexFrontend только отображает результат.
Можно ли использовать один IndexNow endpoint и получить пользу в других поисковиках
Сам протокол IndexNow устроен так, что участвующие поисковые системы договариваются делиться полученными URL между собой. Это описано в официальной спецификации IndexNow.
Но для практической интеграции WebRuta с Яндексом разумнее считать гарантированным только то, что документировано Яндексом для его собственного endpoint:
https://yandex.com/indexnowНе строить бизнес-логику на предположении:
Один POST гарантированно означает одинаковую обработку всеми поисковиками.
У каждого поисковика остаются собственные процессы crawling и indexing.
IndexNow и Google
Здесь важно не создавать ложных ожиданий.
IndexNow не является универсальной командой:
«отправить страницу во все поисковые системы».Для Google по-прежнему актуальны собственные механизмы обнаружения:
crawlable links;
Sitemap;
обычный crawling;
другие поддерживаемые Google инструменты.Поэтому Sitemap и нормальная архитектура сайта всё равно обязательны, даже если Яндекс уведомляется практически мгновенно.
IndexNow и sitemap.xml должны использовать один canonical generator
Например статья:
/expert/articleSitemap generator создаёт:
https://example.ru/expert/articleА IndexNow почему-то:
https://example.ru/expert/article/или:
https://www.example.ru/expert/articleПолучаем расхождение.
Лучше иметь одну функцию
Условно:
getCanonicalPublicUrl(entity)Её используют:
SSR canonical;
Sitemap;
IndexNow;
internal link generator.Тогда URL-policy едина.
Это очень сильный архитектурный принцип
Не четыре subsystem, каждое из которых самостоятельно «угадывает» публичный адрес.
А одна canonical URL model.
Например
Article:
slug = indexnow-na-praktikeФункция возвращает:
https://example.ru/expert/indexnow-na-praktikeИменно этот URL:
в HTML canonical;
в sitemap.xml;
в IndexNow job;
во внутренних ссылках.При переименовании slug
Система знает:
old canonical
new canonicalи может автоматически:
old → 301 newобновить Sitemap и создать IndexNow notification.
Это уже не SEO «после разработки»
Это SEO как часть domain lifecycle.
Как может выглядеть публикационная state machine
Например:
DRAFT
↓
SCHEDULED
↓
PUBLISHED
↓
UPDATED
↓
ARCHIVED
↓
DELETEDДля каждого перехода определяем side effects.
DRAFT → PUBLISHED
создать public URL;
обновить Sitemap;
добавить в listing;
IndexNow(PUBLISHED).PUBLISHED → UPDATED
Если изменение значимо для публичной страницы:
обновить lastmod;
IndexNow(CONTENT_UPDATED).PUBLISHED → DELETED
удалить из Sitemap;
HTTP 404/410;
убрать внутренние ссылки;
IndexNow(DELETED).Slug change
old → 301 new;
Sitemap old remove;
Sitemap new add;
IndexNow URL-change events.Теперь IndexNow становится обычным side effect бизнес-перехода.
Как не потерять уведомление при падении сервера
Плохая реализация:
UPDATE article
COMMIT
sendIndexNow()Между:
COMMITи:
sendIndexNowprocess падает.
Статья опубликована.
Job не существует.
IndexNow потерян.
Надёжнее transactional outbox
В одной транзакции:
UPDATE article
+
INSERT outbox_eventЗатем:
COMMIT.Worker читает:
outbox_event.Теперь возможны только два состояния
Транзакция не прошла:
нет публикации
и нет notification.Транзакция прошла:
публикация есть
и durable событие тоже есть.Это значительно надёжнее callback после commit
Особенно для:
scheduled publishing;
массового импорта;
автоматической публикации.Что если IndexNow job выполнится дважды
Допустим worker:
отправил URL;но умер до:
status = completed.После restart job повторяется.
Это нормально.
IndexNow notification не должен быть финансовой операцией с exactly-once semantics.
Но повторять слишком часто всё равно не нужно
Поэтому можно хранить:
last_accepted_revision.Если уже отправлена:
revision 43и повторно worker видит ту же:
43,можно не создавать лишнюю заявку.
Дедупликация job
Условный ключ:
url + public_revisionили:
entity + revision.Если появилась revision 44
Новая отправка оправдана.
Это полезнее простой дедупликации по URL
Потому что один URL совершенно нормально отправлять:
при первой публикации;
после существенного обновления;
после изменения его состояния.Не удаляйте историю полностью
Полезно знать:
09.10
published
→ accepted 200
12.10
content updated
→ accepted 200
18.10
content updated
→ 429
→ retry
→ accepted 200Это уже audit trail редакционной SEO-системы.
Но не храните бесконечно каждую мелкую попытку без retention
Например подробные HTTP attempts можно хранить:
30–90 днейа итоговое состояние публикационной сущности — дольше.
Конкретный срок зависит от эксплуатации.
IndexNow и scheduled publishing
Для отложенной статьи особенно важно не отправить URL раньше срока.
Например:
publish_at:
15.10.2026 09:0013 октября запись уже существует.
Но IndexNow job не должен создаваться.
В 09:00 scheduler выполняет transaction
SCHEDULED
→ PUBLISHEDТолько теперь:
Sitemap update;
IndexNow event.Это предотвращает преждевременное обнаружение preview URL
И сохраняет правильную связь:
уведомление
следует за реальной публикацией.Массовый импорт старых статей
Допустим в новую CMS перенесено:
500 уже существовавших статейс теми же URL и без фактического изменения контента.
Нужно ли все 500 сразу отправлять?
Не обязательно.
Яндекс прямо рекомендует при подключении IndexNow отправлять изменения, происходящие после начала поддержки протокола, а не пытаться ретроспективно переслать все прошлые изменения сайта.
Sitemap остаётся источником полного набора актуальных URL.
А если миграция реально изменила страницы
Например одновременно:
изменились URL;
контент;
canonical;
структура.Это уже настоящие изменения.
Тогда соответствующие URL могут быть кандидатами на notification.
Как тестировать интеграцию
Проверять только:
fetch() не бросил exceptionнедостаточно.
Нужны tests на полный contract.
Например test key-file
GET /<indexnow-key>.txtожидаем:
200
body = key.Test published article
Создаём:
DRAFT.Ожидаем:
IndexNow jobs = 0.Публикуем.
Ожидаем:
IndexNow jobs = 1.Test repeated draft save
save
save
saveОжидаем:
0 notifications.Test published content update
Меняем публичный контент.
Ожидаем:
new revision notification.Test internal metadata update
Меняем:
admin_note.Ожидаем:
no new IndexNow job.Test deletion
Удаляем опубликованную страницу.
Ожидаем:
URL исчез из Sitemap;
HTTP 404/410;
создан IndexNow deletion notification.Test slug migration
Ожидаем:
old URL → 301;
new URL → 200;
Sitemap → new;
IndexNow events created.Test 429
Mock Яндекса отвечает:
429.Job должен перейти:
RETRYс backoff.
Test 403
Ожидаем:
FAILED_CONFIGURATIONа не бесконечную высокочастотную retry-очередь.
Test server crash
После создания durable job убиваем worker.
После restart:
notification всё равно отправляется.Test duplicate job
Одна revision не должна создавать бесконечные одинаковые внешние запросы.
В итоге IndexNow тоже становится «кодом»
Не ручной кнопкой.
Не CMS-плагином, о котором никто не знает.
А частью проверяемой архитектуры:
content lifecycle
↓
SEO state
↓
durable notification
↓
observable response.Что мониторить после запуска
Полезный dashboard может показывать:
| Метрика | Что она означает |
|---|---|
| Pending | Уведомления ожидают отправки |
| Accepted | Яндекс принял сообщения |
| 202 | Ключ ожидает подтверждения |
| Retry | Временные ошибки |
| Failed | Требуется вмешательство |
| Oldest pending age | Как долго SEO-очередь отстаёт |
| Last successful request | Когда интеграция последний раз реально работала |
Особенно важен oldest pending age
Например:
Pending = 3.На первый взгляд нормально.
Но самый старый:
4 дня.Значит worker фактически сломан.
Ещё полезна метрика accepted/rejected ratio
Если вчера:
99.9% acceptedа после deploy:
0% accepted
403 Invalid key,ошибка обнаруживается сразу.
Можно ли отправлять IndexNow синхронно для маленького сайта
Технически можно.
Но архитектурно даже для небольшого проекта background job обычно безопаснее.
Потому что внешний SEO-сервис:
не должен определять,
успешно ли пользователь
опубликовал статью.Это тот же принцип, что для email
Статья опубликована.
Email-уведомление временно не ушло.
Не нужно откатывать публикацию.
IndexNow — secondary side effect
Критическое состояние:
страница опубликована.Дополнительное:
Яндекс уведомлён.Где проходит граница ответственности IndexNow
IndexNow может ускорить обнаружение изменения.
Но он не решает:
качество страницы;canonical conflicts;robots/noindex;HTTP errors;дубли;плохой SSR;слабый контент;ранжирование.Поэтому ожидание
Подключим IndexNow, и новые статьи сразу будут в топе.
ошибочно сразу на двух уровнях.
Первое:
уведомление ≠ индексирование.Второе:
индексирование ≠ высокий ranking.Реальная последовательность
IndexNow notification
↓
Yandex узнаёт об изменении
↓
crawler / processing
↓
indexing decision
↓
ranking decisionКаждый этап имеет собственные критерии.
IndexNow особенно полезен динамическим сайтам
Например:
новостным;маркетплейсам;каталогам;экспертным центрам;сайтам с часто обновляемыми услугами;редакционным системам.Там изменение URL — обычное событие продукта.
Для сайта из пяти почти неизменных страниц выгода меньше
Яндекс даже отдельно указывает, что для небольшого сайта с несколькими страницами можно использовать ручной инструмент переобхода в Яндекс Вебмастере.
Но если публикации автоматизированы, IndexNow всё равно хорошо ложится в инфраструктуру.
IndexNow особенно хорошо работает не сам по себе, а в связке
Например:
Editorial system
│
├── Canonical URL
├── SSR HTML
├── Sitemap
├── Internal links
├── Robots policy
└── IndexNowВсе эти элементы используют одну публикационную модель.
Тогда статья после публикации автоматически
получает URL;
появляется в /expert;
попадает в Sitemap;
имеет self-canonical;
получает structured data;
и создаёт IndexNow event.Редактор не должен помнить:
Теперь нужно ещё отдельно сообщить Яндексу.
Это и есть зрелая редакционная система
Человек занимается:
содержанием.Приложение занимается:
техническим SEO lifecycle.Практический checklist перед включением IndexNow
- Определён единый production canonical host и генератор публичных URL.
- IndexNow key создан и корректно доступен на сайте.
- Ключ отправляется только backend-системой и не попадает в frontend.
- Новые URL отправляются только после успешной публикации.
- Draft и scheduled материалы не отправляются до фактического появления.
- Существенные изменения публичного контента создают новое уведомление.
- Внутренние изменения БД не создают SEO-события.
- Удалённые страницы корректно меняют HTTP-state и могут отправляться через IndexNow.
- Slug migration синхронизирована с redirect, canonical и Sitemap.
- IndexNow не блокирует основную publication transaction.
- Задания хранятся durable и имеют retry.
200,202,403,422,429обрабатываются как разные состояния.- Одинаковые autosave не создают поток одинаковых запросов.
- Sitemap остаётся полным реестром текущих indexable URL.
- Статус
IndexNow acceptedне называется в интерфейсе «страница проиндексирована». - Есть метрики pending, retries, failures и времени старейшей задачи.
- После deployment выполняется smoke-test key-файла и IndexNow configuration.
Production-схема целиком
Хорошо спроектированная система может выглядеть так:
Редактор
│
▼
Publish article
│
▼
DB transaction
/ | \
/ | \
article=PUBLISHED | outbox event
|
public revision
│
▼
COMMIT
│
┌──────────┴──────────┐
▼ ▼
Public page SEO worker
HTTP 200 │
canonical ├── Sitemap update
content │
└── IndexNow job
│
▼
Yandex IndexNow
│
┌────────────┼────────────┐
▼ ▼ ▼
200 202 error
│ │ │
ACCEPTED PENDING retry/
failedГлавное здесь — отсутствие жёсткой зависимости:
публикация страницыот:
доступности IndexNow.А затем работает обычный поисковый pipeline
Даже после:
IndexNow 200 OKостаётся:
crawl
↓
HTTP
↓
robots
↓
rendering
↓
canonicalization
↓
content evaluation
↓
indexing
↓
rankingIndexNow ускоряет вход в эту цепочку.
Не отменяет её.
Что IndexNow меняет для разработчика
Без него редакционная система говорит:
Страница опубликована. Когда поисковик её заметит — уже его дело.
С ним система может сказать:
Страница опубликована, и поисковой системе автоматически отправлен сигнал об изменении.
Это небольшая разница с точки зрения UI.
Но большая с точки зрения инженерной зрелости.
Потому что notification становится детерминированным
Мы знаем:
когда был создан;
какой URL отправлен;
почему;
какая revision;
какой ответ вернулся;
нужен ли retry.Это уже наблюдаемая интеграция.
Вместо вывода
IndexNow полезнее всего не тогда, когда администратор вручную нажимает:
Отправить URL.
А когда протокол становится естественной частью lifecycle контента.
Новая страница:
Publish
↓
Sitemap
↓
IndexNowСущественно изменённая:
Public revision
↓
lastmod
↓
IndexNowУдалённая:
404/410
↓
remove from Sitemap
↓
IndexNowПереехавшая:
old → 301 new
↓
Sitemap → new
↓
IndexNowПри этом самая важная граница остаётся прежней:
IndexNow accepted
≠
indexedЯндекс официально описывает IndexNow именно как способ сообщить о новых, изменённых или удалённых страницах и прямо предупреждает, что протокол не гарантирует включение переданного URL в индекс.
Поэтому сильная реализация IndexNow состоит не из одного:
fetch('https://yandex.com/indexnow')а из целой небольшой системы:
canonical URL generation
↓
content change detection
↓
durable job
↓
batching / deduplication
↓
API request
↓
response classification
↓
retry
↓
monitoringИ всё это работает рядом с:
sitemap.xml;
robots.txt;
canonical;
HTTP statuses;
SSR;
internal linking.Тогда IndexNow перестаёт быть очередным SEO-плагином.
Он становится нормальным production-механизмом публикации:
если публичная страница действительно изменилась, сайт сам и быстро сообщает об этом поисковой системе — автоматически, наблюдаемо и без участия редактора.