Одна и та же запись в WordPress нередко открывается по нескольким адресам: с ?p=123, через архив, через вложение, с UTM-параметрами, с разными слешами или после смены структуры постоянных ссылок. Для пользователя это почти незаметно, а для SEO и аналитики — уже дубли, размывание веса и лишние обходы краулером.
Ниже — рабочая схема, как найти такие URL, понять источник и закрыть проблему без ломки сайта. Речь не про абстрактную “чистку дублей”, а про конкретные сценарии, которые реально встречаются в WordPress.
Когда проблема уже есть: как быстро это проверить
Сначала не трогайте код. Посмотрите, действительно ли одна запись доступна по нескольким адресам. Самый простой способ — открыть страницу и проверить:
- какой URL в адресной строке после загрузки;
- есть ли в HTML тег
rel="canonical"; - не отдает ли альтернативный адрес тот же контент с кодом
200; - не появляются ли в индексе адреса с параметрами, архивами или вложениями.
Если у вас есть доступ к консоли, проверьте заголовки и редиректы:
curl -I https://example.com/?p=123
curl -I https://example.com/sample-post/
curl -I https://example.com/sample-post/?utm_source=testЕсли все три адреса отдают 200 и контент одинаковый, это уже повод наводить порядок. Нормальная цель — оставить один канонический URL, а остальные либо редиректить, либо явно исключать из индексации в зависимости от сценария.
Откуда в WordPress берутся дубли
Чаще всего источник один из следующих:
Разные форматы постоянных ссылок
WordPress умеет открывать запись и по “красивому” URL, и по старому виду ?p=ID. Если сервер или тема не приводят все варианты к одному адресу, поисковик видит несколько страниц с одинаковым содержимым.
Параметры в URL
UTM-метки, служебные параметры фильтров, сортировки или трекинга часто не меняют контент, но создают новые адреса. Для SEO это типичный источник дублей, особенно если такие ссылки массово попадают в меню, письма и рекламные кампании.
Вложения и attachment-страницы
Если медиафайл имеет собственную attachment-страницу, а изображение еще и встроено в запись, у вас появляется дополнительный URL с тем же или почти тем же содержимым. Для многих сайтов это лишняя страница без самостоятельной ценности.
Архивы и пагинация
Иногда запись доступна и на своей странице, и через архив рубрики, тега или автора. Сами архивы могут быть полезны, но отдельные URL записи в них не должны конкурировать с основной страницей.
Что делать: рабочая схема исправления
Лучше идти по порядку: сначала каноникал, потом редиректы, затем чистка внутренних ссылок. Так проще отследить, где именно проблема была закрыта.
1. Проверьте canonical на записи
На одиночной записи должен быть один канонический адрес. В WordPress это обычно делает ядро, но тема или SEO-плагин могут вмешиваться. Если canonical отсутствует или указывает не туда, сначала ищите конфликт в теме и плагинах.
Проверить можно прямо в шаблоне, если вы временно отлаживаете тему:
<?php
// Временно для диагностики в single.php или через хук wp_head.
if ( is_singular() ) {
global $post;
echo '<!-- canonical: ' . esc_url( get_permalink( $post ) ) . ' -->';
}
?>Это не решение, а способ убедиться, что WordPress считает основным именно тот URL, который вы ожидаете.
2. Настройте 301-редирект с альтернативных адресов
Если старые или альтернативные URL уже гуляют по сайту и внешним ссылкам, лучше отдать 301 на канонический адрес. Для простых случаев это можно сделать на уровне .htaccess или Nginx, но в WordPress часто удобнее закрыть именно логические дубли в коде темы или мини-плагине.
Пример для редиректа старого вида ?p=123 на постоянную ссылку:
<?php
add_action( 'template_redirect', function () {
if ( is_admin() ) {
return;
}
if ( isset( $_GET['p'] ) && is_numeric( $_GET['p'] ) ) {
$post_id = (int) $_GET['p'];
$url = get_permalink( $post_id );
if ( $url ) {
wp_safe_redirect( $url, 301 );
exit;
}
}
} );Если у вас есть конкретные служебные параметры, которые не должны создавать отдельные страницы, их тоже можно приводить к чистому URL. Но не редиректите все подряд: некоторые параметры реально нужны для поиска, фильтрации или авторизации.
3. Уберите лишние attachment-страницы
Если медиа-страницы не нужны, их лучше не индексировать и не использовать как посадочные. В уже опубликованной статье про attachment-страницы мы разбирали индексацию, но здесь важен именно дубль контента: вложение часто повторяет заголовок и изображение записи, не добавляя смысла.
Практический вариант — редиректить attachment на родительскую запись, если она есть:
<?php
add_action( 'template_redirect', function () {
if ( is_attachment() ) {
$parent_id = wp_get_post_parent_id( get_the_ID() );
if ( $parent_id ) {
wp_safe_redirect( get_permalink( $parent_id ), 301 );
exit;
}
}
} );Если родителя нет, лучше не маскировать проблему редиректом на главную без разбора. Для пустых attachment-страниц безопаснее сначала проверить, как они попали в индекс, и уже потом принимать решение.
4. Нормализуйте внутренние ссылки
Даже если canonical и редиректы уже стоят, старые ссылки внутри контента могут продолжать вести на альтернативные адреса. Это особенно заметно после смены структуры постоянных ссылок или переноса сайта.
Проверьте:
- ссылки в меню и виджетах;
- ссылки в старых записях;
- ссылки в шаблонах темы;
- ссылки в письмах и автоворонках, если они ведут на сайт.
Если URL менялся массово, удобнее пройтись поиском по базе и заменить старый формат на новый через безопасный инструмент миграции, а не руками по записям.
Сравнение подходов: плагин, код или сервер
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Плагин SEO/чистки | Нужно быстро закрыть несколько типов дублей | Меньше кода, проще поддержка | Может конфликтовать с темой и уже установленным SEO-плагином |
| Код в мини-плагине | Есть понятный набор дублей и нужен контроль | Прозрачно, легко версионировать | Нужна аккуратность и тестирование |
| Редиректы на сервере | Нужно закрыть старые URL до загрузки WordPress | Быстро и надежно | Сложнее сопровождать, легко ошибиться в правилах |
Если у вас уже стоит плагин для SEO и технической чистки, например Clearfy Pro, часть таких задач можно закрыть без ручного кода. Но если проблема точечная и понятная, мини-плагин часто надежнее: меньше лишней логики и проще понять, что именно делает редирект.
Ссылка для ориентира: Clearfy Pro.
Как проверить, что все сработало
После правок не ограничивайтесь визуальной проверкой в браузере. Нужны минимум три проверки:
- старый URL отдает
301на канонический; - канонический URL отдает
200и содержит правильныйcanonical; - альтернативные адреса больше не появляются в sitemap, внутренних ссылках и поисковой выдаче как отдельные страницы.
Удобно проверить заголовки так:
curl -I https://example.com/?p=123
curl -I https://example.com/sample-post/
# Проверка canonical в HTML
curl -s https://example.com/sample-post/ | grep -i canonicalЕсли используете Search Console, посмотрите отчет по страницам и исключенным URL. Там обычно видно, ушли ли дубли с параметрами, attachment-страницы и старые форматы ссылок.
Частые ошибки и как их исправить
- Редирект на главную вместо канонической записи. Так вы теряете релевантность и создаете плохой пользовательский сценарий. Исправление: редиректить на точную целевую страницу.
- Ставят
noindexвместо редиректа для старых URL. Это не решает проблему дубля, если адрес уже активно используется. Исправление: для устаревших и очевидно лишних URL используйте 301. - Ломают параметры, которые нужны для работы сайта. Например, фильтры, сортировку или вход в личный кабинет. Исправление: разделяйте служебные и SEO-бесполезные параметры.
- Забывают про внутренние ссылки. Даже после редиректа старые URL продолжают расходовать краулинговый бюджет. Исправление: обновите меню, шаблоны и старые записи.
- Конфликтуют SEO-плагин и тема. Два источника canonical или два набора редиректов дают непредсказуемый результат. Исправление: оставьте один ответственный слой за canonical и один за редиректы.
Безопасность и производительность
Не добавляйте редиректы в случайные места шаблона. Если правило должно жить долго, вынесите его в мини-плагин или mu-plugin, чтобы оно не исчезло при обновлении темы. Для высоконагруженных сайтов это еще и вопрос производительности: чем раньше отрабатывает редирект, тем меньше лишней работы делает WordPress.
Мини-плагин для точечных правил выглядит практичнее, чем правка functions.php. Пример каркаса:
<?php
/**
* Plugin Name: WPMy Redirect Fixes
*/
add_action( 'template_redirect', function () {
if ( is_admin() ) {
return;
}
if ( isset( $_GET['p'] ) && is_numeric( $_GET['p'] ) ) {
$url = get_permalink( (int) $_GET['p'] );
if ( $url ) {
wp_safe_redirect( $url, 301 );
exit;
}
}
} );Такой подход проще отключить, протестировать и откатить, если что-то пошло не так.
Когда лучше не писать код вручную
Если дублей много и они разных типов — старые архивы, attachment-страницы, параметры, дубли от темы, дубли от плагинов — сначала составьте список источников. В этом случае удобнее использовать инструмент, который умеет закрывать технические дубли централизованно, а не разбрасывать логику по теме и нескольким сниппетам. Но даже тогда полезно понимать, какой именно URL вы закрываете и почему.
Главный критерий простой: у каждой записи должен быть один основной адрес, а все остальные варианты — либо редиректиться на него, либо не участвовать в индексации по понятной причине. Если это правило соблюдено, сайт становится чище и для поисковика, и для поддержки.