Как скрыть товары WooCommerce от гостей и оставить индексацию для SEO
Сценарий знакомый: магазин уже работает, но часть каталога нельзя показывать всем подряд. При этом товары должны оставаться доступными для поисковых систем, чтобы не потерять органический трафик. На практике это чаще всего нужно для оптовых цен, закрытых коллекций, B2B-каталога, предпродажных страниц или товаров, которые видны только после авторизации.
Самая частая ошибка здесь — пытаться решить задачу через noindex или полное скрытие URL. Тогда гости действительно не видят товар, но поисковик тоже перестает его нормально обходить и ранжировать. Ниже — рабочая схема, где доступ для гостей ограничивается на уровне шаблона или правил доступа, а индексация остается под контролем.
Когда это вообще нужно и что именно ломается
Если просто убрать товар из каталога WooCommerce, он исчезнет не только из витрины, но и из внутренней перелинковки, поиска по сайту, часто — из XML-карты. Если дополнительно поставить noindex, страница может выпасть из поиска полностью. Для закрытого ассортимента это обычно не то, что нужно.
Правильная постановка задачи выглядит так:
- гость не видит карточку товара или видит только заглушку;
- авторизованный пользователь видит полную карточку;
- поисковый робот может обойти URL и получить контент;
- не возникает циклических редиректов и 403 для ботов;
- не ломается корзина и checkout для доступных товаров.
Диагностика проблемы перед изменениями
Сначала проверьте, как именно сейчас ведет себя товар. Это важно, потому что в WooCommerce похожий эффект можно получить разными способами: через видимость каталога, через плагин доступа, через редирект по ролям, через кастомный код в шаблоне.
Что проверить вручную
- Откройте карточку товара в режиме гостя в инкогнито.
- Проверьте, отдается ли страница с кодом
200, редиректом или ошибкой403/404. - Посмотрите исходный HTML: есть ли контент товара или только заглушка.
- Проверьте, не стоит ли на странице
noindexчерез SEO-плагин. - Убедитесь, что товар не исключен из sitemap.
Если у вас есть доступ к серверу, полезно дополнительно проверить ответ через curl:
curl -I https://example.com/product/sample-product/Для поискового робота важен не только статус, но и содержимое страницы. Если вместо товара отдается редирект на главную или пустая страница, индексация будет нестабильной.
Рабочие варианты решения
Есть три практических подхода. Выбор зависит от того, нужно ли скрывать весь товар или только цену и кнопку покупки.
| Подход | Когда подходит | Плюсы | Минусы |
|---|---|---|---|
| Код в теме или мини-плагине | Нужна точная логика по ролям | Контроль, нет лишних зависимостей | Нужно тестировать после обновлений |
| Плагин ограничения доступа | Нужно быстро внедрить без разработки | Меньше кода, проще для контент-менеджера | Может добавлять лишние редиректы или мета-теги |
| Скрытие только цены и кнопки | Товар должен индексироваться, но не продаваться гостям | Сохраняется SEO и структура каталога | Гость видит карточку, но не может купить |
Вариант 1: скрыть товар для гостей через шаблонный фильтр
Если задача — не показывать саму карточку гостям, но оставить URL живым для поисковиков, удобнее всего ограничить вывод на уровне шаблона. Ниже пример: незалогиненным пользователям показывается заглушка, а авторизованным — обычный контент товара.
add_action( 'template_redirect', function () {
if ( ! function_exists( 'is_product' ) || ! is_product() ) {
return;
}
if ( is_user_logged_in() ) {
return;
}
// Не трогаем админку, AJAX и REST.
if ( is_admin() || wp_doing_ajax() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
return;
}
// Показываем заглушку вместо полной карточки.
status_header( 200 );
nocache_headers();
get_header();
echo '<main class="site-main">';
echo '<h1>Товар доступен только после авторизации</h1>';
echo '<p>Войдите в аккаунт, чтобы увидеть описание, цену и кнопку покупки.</p>';
echo '</main>';
get_footer();
exit;
} );Этот способ подходит, когда вам важно не отдавать гостям сам контент товара. Но есть нюанс: поисковый робот без авторизации увидит заглушку, а не карточку. Для SEO это не всегда приемлемо.
Вариант 2: скрыть только цену и кнопку покупки
Если товар должен индексироваться, но покупка доступна только после входа, лучше оставить описание и изображения, а закрыть цену и кнопку. Это обычно безопаснее для SEO и удобнее для каталога.
add_filter( 'woocommerce_get_price_html', function ( $price, $product ) {
if ( is_user_logged_in() ) {
return $price;
}
if ( is_product() ) {
return '<span class="price login-required">Цена доступна после входа</span>';
}
return $price;
}, 10, 2 );
add_action( 'woocommerce_single_product_summary', function () {
if ( is_user_logged_in() ) {
return;
}
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
}, 1 );На практике удаление add_to_cart лучше делать через отдельную функцию и нужный хук, а не прямо внутри анонимной функции, если логика сложнее. Но для простого кейса этого достаточно, чтобы понять принцип.
Вариант 3: ограничение по ролям через плагин
Если у вас B2B-магазин или закрытый прайс-лист, удобнее использовать плагин доступа к контенту или роли пользователей. Важно не брать решение, которое ставит noindex на все закрытые товары без возможности настройки. Иначе вы быстро потеряете контроль над SEO.
При выборе плагина смотрите на три вещи:
- можно ли ограничивать именно товары, а не весь сайт;
- есть ли настройка поведения для гостей: заглушка, редирект, скрытие цены;
- не добавляет ли плагин лишние редиректы и мета-теги на все страницы магазина.
Пошаговая настройка без потери индексации
Если нужен аккуратный вариант, действуйте так:
- Определите, какие товары должны быть закрыты: все, отдельные категории или только часть ассортимента.
- Решите, что видит гость: заглушку, описание без цены или редирект на страницу входа.
- Проверьте, должен ли товар оставаться в sitemap и в выдаче.
- Добавьте логику ограничения через код или плагин.
- Протестируйте гостевой и авторизованный сценарии отдельно.
- Проверьте, что не изменились canonical, robots meta и статус ответа.
Если вы закрываете только часть каталога, удобнее помечать товары отдельной категорией или пользовательским полем. Тогда логика будет прозрачной и не придется вручную править каждый товар.
Как проверить, что решение сработало
После внедрения не ограничивайтесь визуальной проверкой в браузере. Нужно убедиться, что поведение корректно и для человека, и для поискового робота.
- Откройте товар в инкогнито: гостю должен показываться нужный сценарий.
- Откройте тот же товар под авторизованным пользователем: контент должен быть полным.
- Проверьте HTTP-статус через
curl -I: не должно быть случайного301на главную. - Посмотрите исходный код страницы: нет ли
noindex, если он не нужен. - Проверьте sitemap: товар не должен исчезнуть без причины.
- Прогоните страницу через инструмент проверки URL в Google Search Console, если товар важен для SEO.
Если вы используете заглушку вместо товара, убедитесь, что она не выглядит как soft-404. Пустая страница с одной фразой «доступ закрыт» может восприниматься поисковиком как некачественный контент.
Частые ошибки и как их исправить
Ставят noindex вместо ограничения доступа
Это убирает страницу из поиска, но не решает задачу доступа. Если товар должен ранжироваться, noindex — слишком грубый инструмент.
Делают редирект всех гостей на главную
Такой редирект мешает индексации и ухудшает UX. Если нужен переход, лучше вести на страницу входа или на объясняющую страницу с понятным статусом.
Скрывают товар через CSS
Это плохой вариант: контент остается в HTML, а значит, не решается ни вопрос доступа, ни вопрос контроля индексации. Плюс это легко ломается при обновлении темы.
Забывают про вариации и связанные товары
Если закрыт только родительский товар, а вариации или связанные товары доступны, логика становится непредсказуемой. Проверьте не только карточку, но и блоки related products, upsell и поиск по каталогу.
Безопасность и производительность
Любая логика ограничения доступа должна быть дешевой по ресурсам. Не делайте тяжелые запросы к базе на каждом хите карточки товара. Если проверяете роль или метаполе, используйте стандартные функции WordPress и WooCommerce, а не отдельные запросы через WP_Query внутри шаблона.
Если у вас много закрытых товаров, имеет смысл кэшировать результат проверки доступа на уровне объекта пользователя или через transient, но только если логика действительно сложная. Для простого сценария это избыточно.
Также проверьте, не конфликтует ли решение с кеширующим плагином или серверным кешем. Если гостям и авторизованным пользователям отдается одна и та же закешированная версия страницы, ограничение работать не будет. Для таких страниц обычно нужно исключение из кеша или разделение кеша по кукам авторизации.
Когда лучше не писать код, а взять готовое решение
Если у вас закрытый B2B-каталог, несколько ролей доступа и разные правила для цен, корзины и доставки, готовый плагин часто экономит время. Но даже в этом случае проверяйте, как он ведет себя с SEO. Иногда проще взять плагин для ограничения контента и отдельно настроить мета-теги, чем потом разбирать последствия автоматического noindex.
Если задача шире, чем просто скрыть товар, например нужно еще показывать всплывающее окно с авторизацией, можно связать это с отдельным UI-слоем. Для таких сценариев иногда используют My Popup, но только если он действительно нужен как интерфейсный элемент, а не как костыль вместо нормальной логики доступа.
В итоге рабочая схема всегда одна: сначала определяете, что именно должно быть скрыто, потом решаете, как это увидят гости и поисковики, и только после этого выбираете код или плагин. Если перепутать порядок, можно легко получить либо закрытый каталог без трафика, либо индексируемые товары без контроля доступа.
}