301 редирект — это ответ сервера, который говорит браузеру и поисковому роботу: страница переехала навсегда, вот её новый адрес. От остальных способов «перекинуть» посетителя он отличается тем, что переносит в индекс не только адрес, но и накопленный вес ссылок. Ниже — готовые правила для .htaccess под типовые задачи, их аналоги для nginx и разбор ошибок, из-за которых переезд стоит сайту трафика.
Как это работает
Сервер отвечает на запрос кодом 301 и заголовком Location с новым адресом. Браузер сразу уходит туда, обычно незаметно для посетителя, и кеширует этот переход. Поисковик поступает так же: заменяет в индексе старый URL новым и передаёт ему ссылочный вес.
Разница между кодами важна и стоит денег:
| Код | Что означает | Когда применять |
|---|---|---|
| 301 | Переехало навсегда | Смена домена, адреса страницы, склейка зеркал, переход на HTTPS |
| 302 | Временно | Акция на пару недель, техработы, A/B-тест |
| 307 | Временно, метод запроса сохраняется | То же, но для POST-запросов |
| 308 | Навсегда, метод сохраняется | Редкий случай: переезд API, где важен POST |
| 410 | Удалено навсегда | Страницы больше нет и замены ей нет |
Путать 301 и 302 — самая дорогая ошибка в этом списке: при 302 поисковик оставляет в индексе старый адрес и вес на новый не передаёт.
Правила для .htaccess
Все примеры рассчитаны на Apache с включённым mod_rewrite. Блок правил ставится в начало файла .htaccess в корне сайта — до правил CMS, иначе WordPress перехватит запрос раньше.
RewriteEngine On
RewriteBase /
Одна страница на другую
# простой вариант
Redirect 301 /old-page/ https://site.com/new-page/
# тот же результат через mod_rewrite, если остальные правила тоже на нём
RewriteRule ^old-page/?$ https://site.com/new-page/ [R=301,L]
Склейка зеркал: с www на без www
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
Обратный случай, когда главным зеркалом выбран домен с www:
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Переход на HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
За Cloudflare или другим прокси условие %{HTTPS} не сработает — до сервера запрос доходит уже по HTTP. Там проверяют заголовок:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
HTTPS и без www одним правилом
Главный приём этого раздела: не ставить два правила подряд, иначе получится цепочка из двух переходов.
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteRule ^(.*)$ https://site.com/$1 [R=301,L]
Слеш на конце адреса
# добавить слеш
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !.[a-zA-Z0-9]{1,5}$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ /$1/ [R=301,L]
# убрать слеш
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
Условия с !-f и !-d здесь не формальность: без них правило начнёт переписывать адреса картинок и существующих папок.
Переезд на новый домен
# с сохранением адресов страниц — так и нужно делать
RewriteCond %{HTTP_HOST} ^(www.)?old-site.com$ [NC]
RewriteRule ^(.*)$ https://new-site.com/$1 [R=301,L]
# всё на главную — только если структура нового сайта совсем другая
RewriteRule ^(.*)$ https://new-site.com/ [R=301,L]
Второй вариант поисковики часто считают «мягкой 404» и вес не передают. Переносите адрес в адрес везде, где это возможно, а на главную отправляйте только то, чему замены нет.
Раздел на раздел и адреса с параметрами
# /blog/статья/ → /news/статья/
RewriteRule ^blog/(.*)$ /news/$1 [R=301,L]
# ?id=12 → /catalog/sofa/
RewriteCond %{QUERY_STRING} (^|&)id=12(&|$)
RewriteRule ^index.php$ /catalog/sofa/? [R=301,L]
Знак вопроса в конце цели отбрасывает исходную строку параметров — без него она приклеится к новому адресу.
То же самое на nginx
У nginx нет .htaccess: правила живут в конфиге сервера и применяются после nginx -t и перезагрузки.
server {
listen 80;
server_name www.site.com site.com;
return 301 https://site.com$request_uri;
}
# одна страница на другую
location = /old-page/ {
return 301 https://site.com/new-page/;
}
# раздел на раздел
rewrite ^/blog/(.*)$ /news/$1 permanent;
Конструкция return 301 быстрее, чем rewrite, и читается однозначно, поэтому для простых случаев берут именно её.
Частые ошибки
- Цепочка редиректов. www → без www → https → слеш: четыре запроса вместо одного. Собирайте условия в одно правило.
- Цикл. Правило отправляет страницу само на себя, браузер показывает
ERR_TOO_MANY_REDIRECTS. Обычно причина — редирект на HTTPS за прокси по%{HTTPS}. - 302 вместо 301. Переезд сделан, а вес остался на старом адресе.
- Всё на главную. Массовый редирект сотен страниц в корень поисковик считает подменой 404.
- Правила после правил CMS. В
.htaccessWordPress перехватит запрос первым, и ваше правило не сработает: ставьте свой блок выше. - Редирект вместо canonical. Если обе страницы нужны людям, а дублируется только содержимое, ставят
rel="canonical", а не 301. - Забытые внутренние ссылки. После переезда ссылки внутри сайта должны вести на новый адрес напрямую, иначе каждый переход посетителя идёт через редирект.
Как проверить
Быстрее всего — командой в терминале. Ключ -I запрашивает только заголовки, -L идёт по цепочке до конца:
curl -sIL https://site.com/old-page/ | grep -E "HTTP/|Location"
Правильный ответ выглядит так: один HTTP/1.1 301, один Location и затем HTTP/2 200. Два и больше 301 подряд — это цепочка, её нужно схлопнуть. В Search Console тот же результат виден в отчёте «Индексирование страниц», а в браузере — во вкладке Network, если включить «Preserve log».
После массового переезда проверьте выборку из двух-трёх десятков адресов: главную, категории, карточки, страницы с параметрами и адреса из топа поисковой выдачи.
Коротко о главном
301 — для постоянного переезда, 302 — для временного, 410 — для того, чего больше нет. Правило пишется одно и ведёт сразу на конечный адрес, без промежуточных шагов. Проверять нужно всегда — curl -sIL отвечает на вопрос за секунду.
Если переезд большой — смена домена, объединение сайтов, переход на HTTPS с перестройкой адресов — напишите нам: составим карту соответствий и перенесём так, чтобы трафик остался на месте.





