В октябре 2021 года Яндекс презентовал новый протокол для "ускорения интернета". Он позволяет оповещать поисковики об изменениях на сайте через API. Теперь не надо ждать пока поисковой робот зайдет на сайт и заметит новую/обновленную страницу.
Распространение IndexNow началось 18 октября 2021 г. на условиях лицензии Attribution-ShareAlike Creative Commons License. Однако доступен этот протокол далеко не всем поисковикам. Как сообщили CNews представители «Яндекса», протокол работает исключительно в Bing (принадлежит Microsoft) и в поисковой системе самого «Яндекса».
Как работать с IndexNow в Bitrix
Наш алгоритм:
- Создать ключ для проверки прав сайта Яндексом
- Добавить событие на обновление элементов инфоблока
- Получить адрес на сайте обновленного элемента
- Отправить информацию в Яндекс
Ключ для проверки прав сайта
Первым делом можно придумать ключ. Состоять он может из латинских символов, цифр и тире. Длина - от 8 до 128 символов.
Чтобы в будущем понимать для чего этот ключ, начните его с indexnow-. Себе я, например, сделаю ключ indexnow-EkpkVj75fj.
Теперь в корне сайта надо создать файл где имя файла - ваш-ключ.txt, контент файла - этот же ключ.
Наш файл должен открываться по адресу https://наш_сайт.ру/indexnow-EkpkVj75fj.txt
Событие на обновление элементов
В файл local/php_inerface/init.php или, если его нет, то в файл /bitrix/php_interface/init.php, добавьте следующий код:
<?
// Добавляем события на добавление, обновление, удаление элементов
AddEventHandler('iblock', 'OnAfterIBlockElementAdd', ['IndexNow', 'onElementAdd']);
AddEventHandler('iblock', 'OnAfterIBlockElementUpdate', ['IndexNow', 'onElementUpdate']);
AddEventHandler('iblock', 'OnBeforeIBlockElementDelete', ['IndexNow', 'onElementDelete']);
class IndexNow {
const KEY = 'indexnow-EkpkVj75fj'; // ключ, который сохранили в корень сайта
const HOST = 'r-morozov.ru'; // хост сайта
// Событие при добавлении элемента
public static function onElementAdd(&$arFields) {
if (! $arFields['ID']) {
return;
}
self::addIblockElement($arFields['ID']);
}
// Событие при обновлении элемента
public static function onElementUpdate(&$arFields) {
if (! $arFields['RESULT']) {
return;
}
self::addIblockElement($arFields['ID']);
}
// Событие при удалении элемента
public static function onElementDelete($id) {
self::addIblockElement($id);
}
// Добавляем ссылку на элемент в очередь на отправку в IndexNow
public static function addIblockElement($id) {
$detailPage = self::getDetailPageUrl($id);
if (! $detailPage) {
return;
}
self::saveLink('https://' . self::HOST . $detailPage);
}
// Получить ссылку на элемент инфоблока
public static function getDetailPageUrl($id) {
$res = CIBlockElement::GetList([], [
'ID' => $id,
], false, false, [
'ID', 'IBLOCK_ID', 'DETAIL_PAGE_URL',
]);
if ($arItem = $res->GetNext() and ! empty($arItem['DETAIL_PAGE_URL'])) {
return $arItem['DETAIL_PAGE_URL'];
}
}
// Сохранить ссылку в очередь
public static function saveLink($link)
{
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/indexnow.txt', $link . PHP_EOL, FILE_APPEND);
}
// Отправить все ссылки в IndexNow
public static function executeLinks()
{
$links = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/indexnow.txt');
$links = explode(PHP_EOL, $links);
$links = array_unique($links);
$links = array_filter($links);
$links = array_values($links);
if (! count($links)) {
return;
}
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/indexnow.txt', '');
$result = self::sendLinks($links);
if ($result['success'] !== true) {
// Если неуспешно - вывести ошибку в панели администратора
CAdminNotify::Add([
'MESSAGE' => 'Произошла ошибка при работе IndexNow. Сообщение: "' . $result['message'] . '"',
'TAG' => 'INDEX_NOW',
'NOTIFY_TYPE' => CAdminNotify::TYPE_ERROR
]);
}
}
// Отправить ссылки в IndexNow
public static function sendLinks($links) {
$payload = json_encode([
'host' => self::HOST,
'key' => self::KEY,
'urlList' => $links,
]);
$ch = curl_init('https://yandex.com/indexnow');
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
}
Так же создайте файл /local/executeIndexnow.php с контентом:
<?php
$_SERVER['DOCUMENT_ROOT'] = realpath(__DIR__ . '/..');
include $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
IndexNow::executeLinks();
include $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php';
И добавьте запуск файла /local/executeIndexnow.php в крон раз в минуту.
Тестирование
Чтобы протестировать всё ли запускается и уходит:
- Пересохраните запись в инфоблоке в админке
- Проверьте создался ли файл /upload/indexnow.txt, в котором должна быть ссылка на пересохраненную запись. (на публичную часть).
- Откройте через браузер файл /local/executeIndexnow.php.
- Перейдите в панель администратора - ошибок быть не должно. Файл /upload/indexnow.txt должен очиститься.
Пример ошибки в админке:
Смотрите так же: отправка ссылок в IndexNow Online для любых CMS!
Вопросы
Надо ли отправлять запросы во все поисковые системы?
Хотя IndexNow использует на данный момент 2 поисковика, отправлять данные везде не стоит. Согласно протокола, поисковые системы, подключенные к IndexNow оповещают об изменениях друг друга самостоятельно. Достаточно отправить данные в одну из систем.
Как часто можно отправлять ссылки?
Яндекс говорит так: ограничений никаких нет, можно отправлять данные в любом количестве и с любой скоростью.
Но в то же время упоминается ответ HTTP 429 Too Many Requests, который говорит о том, что данные отправляются слишком часто.
Я отправил URL-адрес, что будет дальше?
IndexNow.org:
Если поисковым системам «понравится» ваш URL-адрес, поисковые системы попытаются просмотреть его, чтобы быстро получить последнее содержимое, исходя из логики планирования обхода контента и квоты обхода контента для вашего сайта.
Что значит «понравится» ваш URL-адрес - не уточняется.
Я отправил URL-адрес, но не вижу, что он проиндексирован.
Использование IndexNow гарантирует, что поисковые системы будут знать об изменениях на вашем сайте. Использование IndexNow не гарантирует, поисковые системы будут выполнять обход контента или индексирование веб-страниц. Может потребоваться время, чтобы изменение отразилось в поисковых системах.
У меня используется несколько доменов, могу ли я использовать один ключ?
Один ключ можно использовать на неограниченном количестве доменов, но файл с ключем надо разместить на всех сайтах.
Помощь с добавлением IndexNow на ваш сайт
Если вам требуется помощь, пишите в телеграм:
Отличная статья, все настроил, спасибо!
Спасибо за готовую инструкцию!
Здравствуйте. Подскажите новичку как /local/executeIndexnow.php в крон добавить, читал статью на сайте Битрикса Роберта Басырова так и не понял как это делается. Спасибо
Здравствуйте, написал статью по добавлению php скриптов в крон https://r-morozov.ru/php/dobavlenie-php-skripta-v-cron/
Спасибо
Добрый вечер. Спасибо. Всё работает.
Есть одно замечание. Торговые предложения размещены на одной странице и получается, что когда плагин Импорт из XML и YML от esolutions обновляет торговые предложения, то в Яндекс отправляются куча ссылок дубляжей.
Скриншот: https://i.yapx.ru/PSEuV.png
Можно ли перед отправкой чистить дубляжи?
Перед отправкой и так чистятся дубляжи, это делает строчка
$links = array_unique($links);
Добрый день! На сайте нет файла Init.php в local/php_inerface/ и в /bitrix/php_interface/ Как быть в этом случае? Создать файл самостоятельно по указанному адресу или код нужно будет разместить в другом файле?
Вначале проверить наличие /local/php_interface/init.php, если его нет, проверить наличие /bitrix/php_interface/init.php, если и его нет, то создать /local/php_interface/init.php
Роман, огромное вам спасибо! Замечательная статья! Сделал все по инструкции и получилось, хотя сам не программист.
Единственное у вас на сайте есть статья для добавления Indexnow на сайты joomla https://r-morozov.ru/tools/indexnow-online-wordpress-bitriks/#Indexnow_Joomla но там ничего не описано, указано только, что требуется ссылка на запись и созданный код. Какая ссылка и кокой код мне не понятно. буду благодарен за чуть более понятную инструкцию, спасибо.