Служебные URL в WordPress часто попадают в индекс не потому, что сайт «плохо настроен», а потому что их никто отдельно не ограничил. Типичный пример — /wp-admin/admin-ajax.php, /wp-json/ и страницы с параметрами, которые отдают технический или дублирующий контент. Поисковику такие адреса не нужны: они размывают индекс, создают мусорные страницы и иногда мешают аналитике.
Ниже — рабочий сценарий: как понять, что именно индексируется, чем закрывать такие URL, где достаточно noindex, а где лучше вообще убрать доступ из карты сайта и внутренних ссылок.
Когда проблема действительно есть
Не стоит закрывать всё подряд. Сначала проверьте, что именно уже попало в индекс или в обход поисковых роботов. Для этого достаточно нескольких быстрых проверок:
- введите в поиске
site:example.com wp-jsonиsite:example.com admin-ajax; - посмотрите отчёт по страницам в Google Search Console или Яндекс Вебмастере;
- откройте исходный код страниц и проверьте, нет ли ссылок на технические URL в меню, футере, виджетах и sitemap;
- проверьте, не отдают ли служебные эндпоинты HTML-страницу с заголовком и мета-тегами вместо ожидаемого JSON или пустого ответа.
Если в индексе есть только один-два технических адреса, обычно хватает точечной правки. Если же поисковик видит десятки URL с параметрами, сначала нужно убрать источник генерации ссылок, а уже потом ставить ограничения.
Что именно закрывать, а что не трогать
В WordPress есть несколько разных типов служебных адресов. У них разная роль, поэтому и подход к ним отличается.
| Что закрываем | Какой риск | Что делать |
|---|---|---|
/wp-admin/admin-ajax.php | Может индексироваться как техническая страница, особенно если плагин отдаёт HTML | Не добавлять в sitemap, при необходимости закрыть от индексации через robots и заголовки |
/wp-json/ и отдельные REST-эндпоинты | Появляются в индексе как дубли или служебные страницы | Ограничить индексацию только для публично не нужных маршрутов |
| URL с параметрами фильтров, сортировки, поиска | Размножают дубли | Убрать из внутренних ссылок, при необходимости использовать canonical и noindex |
| Служебные страницы плагинов | Могут светить технический контент | Проверить настройки плагина и исключить их из sitemap |
Важно: не закрывайте весь REST API целиком, если тема, плагин или фронтенд реально используют его для работы. В WordPress REST API нужен не только для внешних интеграций, но и для редактора, блоков и некоторых интерфейсов.
Диагностика: откуда берутся лишние URL
Перед правками нужно понять источник. Обычно это один из трёх вариантов: ссылка в шаблоне, генерация плагином или автоматическая индексация параметров.
Проверка sitemap и внутренних ссылок
Откройте XML-карту сайта и найдите там служебные адреса. Если они есть, проблема не в поисковике, а в генераторе sitemap. Часто это SEO-плагин или кастомный код, который добавил лишний тип записи или endpoint.
Затем проверьте HTML-страницы на наличие ссылок на /wp-json/ и admin-ajax.php. Иногда они попадают в разметку через JS-обёртки, data-атрибуты или неаккуратные шаблоны.
Проверка ответа сервера
Если служебный URL отдаёт 200 OK и полноценную HTML-страницу, поисковик может попытаться её индексировать. Для технических эндпоинтов лучше, чтобы ответ был либо JSON, либо корректный статус для несуществующего маршрута, либо явный запрет индексации.
curl -I https://example.com/wp-json/Смотрите на три вещи: статус, Content-Type и наличие заголовков, которые запрещают индексацию. Если вместо JSON вы видите HTML-шаблон темы, значит где-то есть конфликт маршрутизации или плагин перехватывает вывод.
Пошаговое решение без поломки сайта
Лучше идти от мягких ограничений к жёстким. Сначала уберите источник дублей, потом добавьте запрет на индексацию, и только в конце — блокировку в robots.txt, если она действительно нужна.
Шаг 1. Уберите лишние ссылки из шаблонов и sitemap
Если служебный URL попал в карту сайта или в навигацию, поисковик будет находить его снова и снова. Проверьте:
- шаблоны header/footer;
- виджеты и блоки;
- настройки SEO-плагина;
- кастомные функции, которые выводят ссылки на REST endpoints или AJAX-адреса.
Если у вас есть кастомный код, не вставляйте служебные адреса в HTML без необходимости. Для AJAX лучше держать URL в JavaScript и использовать nonce, а не публиковать его в разметке.
Шаг 2. Добавьте noindex для технических страниц
Если URL должен открываться для работы сайта, но не должен индексироваться, используйте noindex. Для отдельных маршрутов это можно сделать через заголовок X-Robots-Tag.
add_action('template_redirect', function () {
if (strpos($_SERVER['REQUEST_URI'], '/wp-json/') === 0) {
header('X-Robots-Tag: noindex, nofollow', true);
}
});Этот вариант подходит не для всех REST-запросов подряд, а только для тех маршрутов, которые вы реально хотите скрыть от индексации. Если API используется публично, не ставьте запрет без анализа последствий.
Шаг 3. Закройте служебные URL в robots.txt только как дополнительный слой
robots.txt не удаляет URL из индекса мгновенно и не заменяет noindex. Но он полезен, чтобы поисковик не тратил краулинговый бюджет на технические адреса.
User-agent: *
Disallow: /wp-admin/
Disallow: /wp-admin/admin-ajax.php
Disallow: /wp-json/С wp-admin обычно всё понятно, но с admin-ajax.php и wp-json нужно быть аккуратнее. Если какой-то плагин или фронтенд-логика завязаны на эти адреса, запрет в robots не ломает работу сам по себе, но может мешать диагностике и индексации нужных публичных данных.
Шаг 4. Для параметров используйте canonical и контроль генерации URL
Если проблема не в служебном endpoint, а в URL с параметрами, не пытайтесь лечить это только robots. Лучше убрать генерацию лишних ссылок и оставить один канонический адрес. Для страниц фильтров и сортировки это часто даёт больший эффект, чем запрет на обход.
Пример: если на архиве появляются URL вида ?sort=price или ?view=grid, проверьте, действительно ли они должны существовать как отдельные страницы. Если нет — не выводите их в sitemap и не делайте на них внутренние ссылки.
Пример: закрываем REST-маршрут только для поисковиков
Иногда нужно оставить endpoint доступным для приложения, но не давать ему индексироваться. В таком случае удобнее добавить заголовок только для конкретного маршрута.
add_action('rest_api_init', function () {
register_rest_route('myplugin/v1', '/private-data', array(
'methods' => 'GET',
'callback' => 'myplugin_private_data',
'permission_callback' => function () {
return current_user_can('manage_options');
},
));
});
add_filter('rest_post_dispatch', function ($result, $server, $request) {
$route = $request->get_route();
if ($route === '/myplugin/v1/private-data') {
$result->header('X-Robots-Tag', 'noindex, nofollow');
}
return $result;
}, 10, 3);Здесь важны две вещи: маршрут ограничен правами, а заголовок X-Robots-Tag ставится только на нужный endpoint. Так вы не ломаете весь REST API и не закрываете публичные данные, которые нужны фронтенду.
Как проверить, что решение сработало
После внедрения не ограничивайтесь визуальной проверкой. Нужны конкретные признаки, что поисковик видит изменения.
- служебный URL больше не появляется в sitemap;
- в ответе сервера есть
X-Robots-Tag: noindexтам, где он нужен; - внутренние ссылки на технические адреса удалены;
- в Search Console или Вебмастере статус URL меняется с «проиндексировано» на «исключено» или «не выбрано каноническое» в зависимости от ситуации;
curl -Iпоказывает ожидаемые заголовки и статус ответа.
Для быстрой проверки удобно использовать команду:
curl -I https://example.com/wp-json/myplugin/v1/private-dataЕсли заголовок X-Robots-Tag не пришёл, значит код не сработал или маршрут обрабатывается не там, где вы его повесили. Если URL всё ещё в индексе, это нормально на коротком промежутке: поисковику нужно время, чтобы переобойти страницу и увидеть запрет.
Частые ошибки и как их исправить
Закрыли весь REST API, а редактор начал вести себя странно
Такое бывает, если запрет сделали слишком грубо на уровне сервера или плагина безопасности. Решение — убрать глобальный блок и ограничить только конкретные маршруты, которые реально не нужны в индексе.
Добавили Disallow в robots.txt и ждали удаления из индекса
robots.txt не удаляет уже проиндексированные URL сам по себе. Если страница уже в индексе, нужен noindex или корректный 404/410, а затем переобход.
Скрыли URL, но оставили на него внутренние ссылки
Поисковик продолжит находить адрес через ссылки на сайте. Сначала уберите источник, потом закрывайте индексацию. Иначе URL будет возвращаться в обходе снова и снова.
Поставили noindex на страницу, которая должна ранжироваться
Это уже ошибка настройки, а не оптимизации. Перед правкой проверьте, не используется ли URL для публичного контента, который нужен в поиске. Особенно это касается REST-эндпоинтов, которые отдают данные для фронтенда и одновременно доступны по прямой ссылке.
Безопасность и производительность: что учесть дополнительно
Если вы работаете с AJAX и REST API, не ограничивайтесь только индексацией. Убедитесь, что у публичных endpoint’ов есть проверка прав доступа там, где это нужно, и nonce для запросов из админки или фронтенда. Индексация и безопасность — разные задачи, но они часто пересекаются.
Для производительности полезно не только закрывать мусорные URL, но и уменьшать количество запросов к admin-ajax.php. Если фронтенд делает много однотипных обращений, лучше пересмотреть архитектуру: объединить запросы, кэшировать ответы там, где это безопасно, и не создавать лишние endpoint’ы ради одной мелкой функции.
Если вы используете SEO-плагин и он уже умеет управлять noindex, canonical и sitemap, не дублируйте его логику в теме. Двойная настройка часто приводит к конфликтам: один код ставит запрет, другой тут же его снимает или генерирует ссылку обратно.
В проектах, где нужно быстро убрать дубли и технические страницы, иногда удобнее использовать специализированный инструмент вроде Clearfy Pro от WPShop: он помогает навести порядок в дублях, служебных URL и части технических настроек. Но даже в этом случае сначала проверьте, какие именно адреса вы хотите закрыть, а какие должны оставаться доступными для работы сайта.
Если вы хотите, чтобы служебные URL перестали мешать индексации, действуйте по порядку: найдите источник, уберите лишние ссылки, поставьте точечный noindex, и только потом дополняйте это robots.txt. Такой подход обычно даёт предсказуемый результат и не ломает рабочие сценарии WordPress.