Redirects are one of the most important technical aspects of SEO. They can significantly improve a site's search rankings or seriously harm them. Proper redirect setup is critical when changing domains, changing URL structure, migrating to HTTPS, and in many other scenarios. In this article, we take an in-depth look at redirects and cover all aspects of setting them up and optimizing them correctly.
What redirects are and why they are needed
A redirect is the automatic forwarding of a user or search crawler from one URL to another. It happens at the server level, when the server returns a special HTTP status code telling the browser or search crawler that the requested resource is available at a different address.
The main purpose of redirects is to provide a continuous user experience when a site's structure changes, a domain is changed, or other technical changes are made. Without properly configured redirects, users may land on pages with a 404 error, and search engines may lose the connection between old and new URLs.
History of redirects
Redirects emerged with the development of the HTTP protocol in the early 1990s. Initially, they were used for simple forwarding, but they became more complex and important as web technologies and SEO developed.
In 1999, RFC 2616 was published, standardizing HTTP status codes, including redirect codes. Since then, redirects have become an integral part of web development and SEO optimization.
Types of redirects and their impact on SEO
301 redirect (Permanent Redirect)
A 301 redirect is the most important type of redirect for SEO. It tells search engines that a resource has permanently moved to a new URL.
HTTP/1.1 301 Moved Permanently
Location: https://newdomain.com/new-pageCharacteristics of a 301 redirect:
- Permanent: indicates a permanent move
- SEO value transfer: transfers up to 90-99% of link equity
- Index update: search engines update their index
- Caching: browsers cache the redirect
When to use a 301 redirect:
- Changing domains
- Changing URL structure
- Migrating from HTTP to HTTPS
- Merging pages
- Fixing duplicate content
302 redirect (Temporary Redirect)
A 302 redirect indicates that a resource has moved temporarily. Search engines do not transfer SEO value or update the index.
HTTP/1.1 302 Found
Location: https://example.com/temporary-pageCharacteristics of a 302 redirect:
- Temporary: indicates a temporary move
- No SEO value transfer: search engines do not transfer link equity
- Index retention: the old URL remains in the index
- Temporary caching: browsers may cache the redirect
When to use a 302 redirect:
- A/B testing
- Temporary promotions
- Maintenance
- Geographic redirects
- A/B testing
307 redirect (Temporary Redirect)
A 307 redirect is a stricter version of a 302 redirect that preserves the HTTP request method.
HTTP/1.1 307 Temporary Redirect
Location: https://example.com/new-pageCharacteristics of a 307 redirect:
- Method preservation: POST remains POST; GET remains GET
- Temporary: like 302
- Security: safer for forms and APIs
308 redirect (Permanent Redirect)
A 308 redirect is the permanent version of a 307 redirect.
HTTP/1.1 308 Permanent Redirect
Location: https://example.com/new-pageCharacteristics of a 308 redirect:
- Permanent: like 301
- Method preservation: like 307
- SEO value transfer: like 301
Setting up redirects on different servers
Setting up redirects in Apache (.htaccess)
Apache uses the .htaccess file to configure redirects.
# 301 редирект для смены домена
RewriteEngine On
RewriteCond %{HTTP_HOST} ^olddomain.com$ [NC]
RewriteRule ^(.*)$ https://newdomain.com/$1 [R=301,L]
# 301 редирект для изменения структуры URL
RewriteRule ^old-page\.html$ /new-page [R=301,L]
# 301 редирект для миграции на HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# 302 редирект для временного перемещения
RewriteRule ^temporary-page$ /new-temporary-page [R=302,L]
# Редирект с www на без www
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
# Редирект без www на www
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]Setting up redirects in Nginx
Nginx uses configuration files to set up redirects.
# 301 редирект для смены домена
server {
listen 80;
server_name olddomain.com;
return 301 https://newdomain.com$request_uri;
}
# 301 редирект для миграции на HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# Редирект с www на без www
server {
listen 443 ssl;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
# Редирект без www на www
server {
listen 443 ssl;
server_name example.com;
return 301 https://www.example.com$request_uri;
}
# Редирект для изменения структуры URL
location = /old-page.html {
return 301 /new-page;
}
# Редирект для временного перемещения
location = /temporary-page {
return 302 /new-temporary-page;
}Setting up redirects in PHP
PHP allows redirects to be configured programmatically.
<?php
// 301 редирект
function permanentRedirect($url) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: " . $url);
exit();
}
// 302 редирект
function temporaryRedirect($url) {
header("HTTP/1.1 302 Found");
header("Location: " . $url);
exit();
}
// Пример использования
if ($_SERVER['HTTP_HOST'] === 'olddomain.com') {
$newUrl = 'https://newdomain.com' . $_SERVER['REQUEST_URI'];
permanentRedirect($newUrl);
}
// Редирект для миграции на HTTPS
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
$newUrl = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
permanentRedirect($newUrl);
}
// Редирект для изменения структуры URL
$redirectMap = [
'/old-page.html' => '/new-page',
'/old-category/' => '/new-category/',
'/product/old-name' => '/product/new-name'
];
$currentPath = $_SERVER['REQUEST_URI'];
if (isset($redirectMap[$currentPath])) {
permanentRedirect($redirectMap[$currentPath]);
}
?>Setting up redirects in Node.js
Node.js allows redirects to be configured in web applications.
const express = require('express');
const app = express();
// 301 редирект для смены домена
app.use((req, res, next) => {
if (req.hostname === 'olddomain.com') {
const newUrl = `https://newdomain.com${req.url}`;
return res.redirect(301, newUrl);
}
next();
});
// 301 редирект для миграции на HTTPS
app.use((req, res, next) => {
if (!req.secure && req.get('x-forwarded-proto') !== 'https') {
const newUrl = `https://${req.hostname}${req.url}`;
return res.redirect(301, newUrl);
}
next();
});
// Редирект для изменения структуры URL
const redirectMap = {
'/old-page.html': '/new-page',
'/old-category/': '/new-category/',
'/product/old-name': '/product/new-name'
};
app.use((req, res, next) => {
const newPath = redirectMap[req.path];
if (newPath) {
return res.redirect(301, newPath);
}
next();
});
// 302 редирект для временного перемещения
app.get('/temporary-page', (req, res) => {
res.redirect(302, '/new-temporary-page');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});Complex redirect scenarios
Redirect chains
Redirect chains can significantly slow page loading and negatively affect SEO.
# Плохой пример - цепочка редиректов
RewriteRule ^old-page$ /intermediate-page [R=301,L]
RewriteRule ^intermediate-page$ /final-page [R=301,L]
# Хороший пример - прямой редирект
RewriteRule ^old-page$ /final-page [R=301,L]Redirects with parameters
Redirects that preserve URL parameters.
# Сохранение всех параметров
RewriteRule ^old-page$ /new-page [R=301,L,QSA]
# Добавление параметров
RewriteRule ^old-page$ /new-page?param=value [R=301,L,QSA]
# Условные редиректы
RewriteCond %{QUERY_STRING} ^category=old$
RewriteRule ^page$ /new-page?category=new [R=301,L]Geographic redirects
Redirects based on the user's geographic location.
# Редирект на основе IP
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^RU$
RewriteRule ^$ /ru/ [R=302,L]
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^US$
RewriteRule ^$ /en/ [R=302,L]Redirects for mobile devices
Redirects based on device type.
# Редирект мобильных устройств
RewriteCond %{HTTP_USER_AGENT} (Android|iPhone|iPad|Mobile)
RewriteRule ^$ /mobile/ [R=302,L]Redirect monitoring and analysis
Checking redirects
It is important to regularly check that redirects are working.
#!/bin/bash
# Скрипт для проверки редиректов
echo "Проверка редиректов..."
# Список URL для проверки
urls=(
"https://olddomain.com/page1"
"https://olddomain.com/page2"
"https://example.com/old-page"
)
for url in "${urls[@]}"; do
echo "Проверяем: $url"
# Получаем HTTP-код ответа
status=$(curl -s -o /dev/null -w "%{http_code}" "$url")
# Получаем URL после редиректа
redirect_url=$(curl -s -o /dev/null -w "%{redirect_url}" "$url")
echo "Статус: $status"
echo "Редирект на: $redirect_url"
echo "---"
doneAnalyzing server logs
Log analysis helps assess how effective redirects are.
# Анализ редиректов в логах Nginx
grep "301\|302" /var/log/nginx/access.log | awk '{print $1, $7, $9}' | sort | uniq -c
# Поиск медленных редиректов
awk '$9 ~ /301|302/ && $10 > 1 {print $1, $7, $9, $10}' /var/log/nginx/access.logMonitoring in Google Search Console
Google Search Console provides information about redirects.
// Интеграция с Google Search Console API
async function checkRedirectsInGSC() {
const accessToken = 'your-access-token';
try {
const response = await fetch(
'https://searchconsole.googleapis.com/v1/sites/https%3A%2F%2Fexample.com%2F/urlInspection/index:inspect',
{
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
inspectionUrl: 'https://olddomain.com/page',
siteUrl: 'https://example.com'
})
}
);
const data = await response.json();
console.log('Результат проверки:', data);
} catch (error) {
console.error('Ошибка API:', error);
}
}Optimizing redirects for SEO
Minimizing redirect chains
Redirect chains negatively affect SEO and loading speed.
# Плохо - цепочка редиректов
RewriteRule ^old-page$ /intermediate-page [R=301,L]
RewriteRule ^intermediate-page$ /final-page [R=301,L]
# Хорошо - прямой редирект
RewriteRule ^old-page$ /final-page [R=301,L]Using the correct HTTP status codes
Choosing the correct HTTP status code is critical.
# Постоянное перемещение - 301
RewriteRule ^old-page$ /new-page [R=301,L]
# Временное перемещение - 302
RewriteRule ^temporary-page$ /new-temporary-page [R=302,L]
# Сохранение метода запроса - 307/308
RewriteRule ^api/old-endpoint$ /api/new-endpoint [R=308,L]Updating internal links
It is important to update internal links after setting up redirects.
<?php
// Функция для обновления внутренних ссылок
function updateInternalLinks($content) {
$linkMap = [
'/old-page.html' => '/new-page',
'/old-category/' => '/new-category/',
'https://olddomain.com' => 'https://newdomain.com'
];
foreach ($linkMap as $oldUrl => $newUrl) {
$content = str_replace($oldUrl, $newUrl, $content);
}
return $content;
}
// Обновление ссылок в базе данных
$sql = "UPDATE posts SET content = REPLACE(content, '/old-page.html', '/new-page')";
$pdo->exec($sql);
?>Performance monitoring
Regular monitoring helps identify redirect issues.
// Скрипт для мониторинга производительности редиректов
async function monitorRedirectPerformance() {
const redirects = [
{ from: 'https://olddomain.com/page1', to: 'https://newdomain.com/page1' },
{ from: 'https://example.com/old-page', to: 'https://example.com/new-page' }
];
for (const redirect of redirects) {
const startTime = performance.now();
try {
const response = await fetch(redirect.from, {
method: 'HEAD',
redirect: 'follow'
});
const endTime = performance.now();
const duration = endTime - startTime;
console.log(`Редирект ${redirect.from} -> ${redirect.to}: ${duration}ms`);
// Отправляем данные в аналитику
gtag('event', 'redirect_performance', {
'from_url': redirect.from,
'to_url': redirect.to,
'duration': duration,
'status': response.status
});
} catch (error) {
console.error(`Ошибка редиректа ${redirect.from}:`, error);
}
}
}
// Запускаем мониторинг каждые 5 минут
setInterval(monitorRedirectPerformance, 5 * 60 * 1000);Common mistakes and how to fix them
Error 1: Incorrect HTTP status code
Using 302 instead of 301 for permanent changes.
# Неправильно
RewriteRule ^old-page$ /new-page [R=302,L]
# Правильно
RewriteRule ^old-page$ /new-page [R=301,L]Error 2: Redirect chains
Creating long redirect chains.
# Неправильно - цепочка
RewriteRule ^page1$ /page2 [R=301,L]
RewriteRule ^page2$ /page3 [R=301,L]
RewriteRule ^page3$ /final-page [R=301,L]
# Правильно - прямой редирект
RewriteRule ^page1$ /final-page [R=301,L]Error 3: Lost parameters
Losing important URL parameters during a redirect.
# Неправильно - потеря параметров
RewriteRule ^old-page$ /new-page [R=301,L]
# Правильно - сохранение параметров
RewriteRule ^old-page$ /new-page [R=301,L,QSA]Error 4: No monitoring
Insufficient monitoring of redirect effectiveness.
#!/bin/bash
# Скрипт для регулярной проверки редиректов
# Проверяем редиректы каждые 6 часов
while true; do
echo "$(date): Проверка редиректов..."
# Проверяем основные редиректы
curl -s -o /dev/null -w "%{http_code}" "https://olddomain.com" | grep -q "301" || echo "Ошибка редиректа домена"
# Отправляем отчет
echo "Проверка завершена" | mail -s "Отчет по редиректам" admin@example.com
sleep 21600 # 6 часов
doneConclusion
Redirects are a critical tool for maintaining a site's SEO performance during technical changes. Properly configured redirects can preserve search rankings and provide a continuous user experience.
It is important to remember that redirects should be configured correctly the first time, since fixing errors can take a significant amount of time. Regular monitoring and testing of redirects can help identify problems early and avoid a negative impact on SEO.
Using the correct HTTP status codes, minimizing redirect chains, and regularly updating internal links can help maintain optimal site performance and search rankings.
🔗 Check your site's redirects: rechecker.ru/services/redirects