Przekierowanie 301 – jak je zrobić? Gotowe przykłady: .htaccess, Nginx, PHP, WordPress i Cloudflare

Spis treści

Masz pytanie o swoją stronę?

Umów krótką konsultację – powiem, od czego zacząć.

Żeby zrobić przekierowanie 301, serwer musi na żądanie starego adresu odpowiedzieć kodem 301 Moved Permanently i nagłówkiem Location z nowym adresem. Na hostingu z Apache lub LiteSpeed wystarczy jedna linijka w pliku .htaccess, w Nginx dyrektywa return 301, w PHP funkcja header() z kodem 301, a w WordPressie wtyczka Redirection. Każde przekierowanie po wdrożeniu sprawdzam poleceniem curl -I: stary adres ma zwrócić 301 i od razu wskazać docelowy URL, bez pośrednich skoków.

Poniżej masz gotowe, sprawdzone fragmenty konfiguracji do skopiowania: pojedynczy adres, cała domena, www i bez www, HTTP na HTTPS, Nginx, PHP, WordPress i Cloudflare. Do tego krótka ściąga, kiedy w SEO użyć 301, a kiedy 302, 307 lub 308, oraz błędy, które najczęściej widzę w audytach. To tekst praktyczny. Jeśli chcesz zrozumieć same kody (co mówi specyfikacja HTTP, jak działają z pamięcią podręczną i metodą żądania, czym jest 303 czy 304), zajrzyj do mojego przeglądu kodów odpowiedzi 3xx.

Spis treści

Czym jest i jak działa przekierowanie 301?

Przekierowanie 301 to odpowiedź serwera HTTP z kodem 301 Moved Permanently, która mówi przeglądarce i robotowi Google: „ten zasób na stałe przeniósł się pod inny adres, od teraz używaj nowego”. Przeglądarka nie pokazuje treści starej strony, tylko od razu pobiera adres z nagłówka Location. Tak wygląda to w praktyce (odpowiedź skrócona do najważniejszych nagłówków):

$ curl -I --http1.1 https://domena.pl/stary-adres/
HTTP/1.1 301 Moved Permanently
Location: https://domena.pl/nowy-adres/

Dla SEO najważniejsze jest to, że przekierowanie stałe (301 lub 308) Google traktuje jako silny sygnał, że to adres docelowy powinien być kanoniczny i widoczny w wynikach wyszukiwania. Sygnały ze starego adresu, w tym linki, są konsolidowane na nowym. Dlatego 301 stosuję przy każdej trwałej zmianie: nowym adresie wpisu, zmianie struktury URL-i, przejściu na HTTPS czy przeniesieniu serwisu na nową domenę.

strzałka namalowana na drzewie która wskazuje kierunek dokładnie tak jak przekierowania 301 oraz 302 wskazują drogę przeglądarkom i robotom Google
Photo by Markus Spiske on Pexels.com

301, 302, 307 czy 308 – którego przekierowania użyć?

W 9 na 10 przypadków potrzebujesz 301. Wybór sprowadza się do jednego pytania: czy zmiana jest trwała? Jeśli tak – 301 (albo 308). Jeśli to tylko na chwilę – 302 (albo 307). Specyfikację, historię i niuanse techniczne poszczególnych kodów opisałem osobno w artykule o kodach odpowiedzi 3xx. Tutaj ściąga do decyzji:

KodRodzajKiedy stosować
301TrwałeZmiana adresu na stałe: nowy slug, nowa struktura, HTTPS, nowa domena. Domyślny wybór w SEO.
302TymczasoweZmiana na chwilę: prace serwisowe, krótka promocja, test. Stary adres zostaje w indeksie.
307TymczasoweJak 302, ale przeglądarka musi powtórzyć żądanie tą samą metodą (np. POST). Dla Google to to samo co 302. Spotkasz go głównie w API i aplikacjach JavaScript.
308TrwałeJak 301, ale z zachowaniem metody HTTP. Google traktuje go tak samo jak 301.

301 vs 302 w SEO: przy 301 Google traktuje przekierowanie jako silny sygnał, że kanoniczny jest adres docelowy, więc z czasem to on pojawia się w wynikach. Przy 302 to tylko słaby sygnał i w wynikach zwykle zostaje stary adres. 301 vs 308 i 302 vs 307: Google traktuje 308 tak samo jak 301, a 307 tak samo jak 302. Różnią się tylko tym, czy przeglądarka może zamienić metodę POST na GET, co ma znaczenie dla formularzy i API, a nie dla zwykłych stron.

Przekierowanie 302 – co to jest i jak je zrobić

Przekierowanie 302 (302 Found) mówi: „zasób jest chwilowo pod innym adresem, ale wracaj pod stary”. Używasz go, gdy zmiana jest na chwilę: prace serwisowe na jednej podstronie, krótka promocja, test A/B z osobnymi adresami wariantów. Robisz je tak samo jak 301, zmieniasz tylko kod:

# .htaccess (Apache, LiteSpeed)
Redirect 302 /promocja/ https://domena.pl/promocja-jesien/

# Nginx
location = /promocja/ {
    return 302 https://domena.pl/promocja-jesien/$is_args$args;
}

# PHP
<?php
header('Location: https://domena.pl/promocja-jesien/', true, 302);
exit;

Uważaj na odwrotną sytuację: wiele narzędzi (PHP, wp_redirect(), flaga R w mod_rewrite) bez podania kodu wysyła właśnie 302, choć zmiana jest trwała. Piszę o tym w sekcji o błędach. Jeśli „tymczasowa” zmiana zostaje na stałe, zamień 302 na 301, zamiast liczyć, że Google sam się domyśli.

Przekierowanie 307 i 308 – kiedy i jak

307 (Temporary Redirect) to tymczasowe przekierowanie, przy którym przeglądarka musi zachować metodę żądania. 308 (Permanent Redirect) to jego stały odpowiednik. Przy zwykłej stronie firmowej czy blogu ustawiam je rzadko. Przydają się, gdy przenosisz endpointy przyjmujące formularze lub żądania API metodą POST i dane nie mogą zginąć po drodze. Składnia jest identyczna jak przy 301:

# .htaccess (Apache, LiteSpeed)
Redirect 307 /api/zamowienie https://domena.pl/api/v2/zamowienie
Redirect 308 /api/koszyk https://domena.pl/api/v2/koszyk

# Nginx
location = /api/koszyk {
    return 308 https://domena.pl/api/v2/koszyk$is_args$args;
}

Czasem 307 i 308 pojawiają się same. Next.js przy przekierowaniach w next.config.js wysyła 308 dla permanent: true i 307 dla permanent: false. Dla Google to bez znaczenia, więc nie musisz tego „poprawiać” na 301. Z kolei „307 Internal Redirect” w narzędziach deweloperskich Chrome to zwykle nie Twój serwer, tylko mechanizm HSTS w przeglądarce. Wyjaśniam go w tekście o kodach 3xx.

Jak zrobić przekierowanie 301 – krok po kroku

  1. Zrób listę starych adresów. Eksport z crawlera (np. Screaming Frog), mapy witryny, raportu „Skuteczność” w Google Search Console i adresów z linkami zewnętrznymi.
  2. Przypisz każdemu staremu adresowi odpowiednik. Przekierowanie ma prowadzić do strony o tej samej lub bardzo podobnej treści, a nie hurtowo na stronę główną.
  3. Wybierz miejsce wdrożenia. Najlepiej na serwerze (.htaccess, konfiguracja Nginx) lub na brzegu CDN (Cloudflare). Wtyczka w CMS-ie też jest w porządku. JavaScript i meta refresh to ostateczność.
  4. Wdróż reguły i od razu je przetestuj (curl -I, opis niżej). Przed edycją .htaccess zrób kopię pliku, bo jedna literówka potrafi położyć całą stronę błędem 500.
  5. Zaktualizuj linki wewnętrzne, mapę witryny i tagi canonical, tak żeby wskazywały od razu nowe adresy. Przekierowanie ma łapać ruch z zewnątrz, a nie obsługiwać nawigację w Twoim serwisie.
  6. Utrzymuj przekierowania co najmniej rok, a najlepiej bezterminowo. Google przy przenosinach serwisu zaleca trzymać je „tak długo, jak to możliwe, zwykle co najmniej rok”, a z perspektywy użytkowników nawet na stałe.

Przekierowanie 301 w .htaccess (Apache i LiteSpeed)

Plik .htaccess leży w katalogu głównym strony (zwykle public_html). Obsługuje go Apache i LiteSpeed, więc poniższe przykłady działają na większości polskich hostingów współdzielonych. W WordPressie wklejaj reguły nad blokiem # BEGIN WordPress, bo WordPress nadpisuje wszystko, co jest między znacznikami # BEGIN i # END. Kolejność też ma znaczenie: reguła musi zadziałać, zanim WordPress przechwyci żądanie.

Przekierowanie pojedynczego adresu URL

Najprostsza wersja to dyrektywa Redirect z modułu mod_alias:

Redirect 301 /stary-adres/ https://domena.pl/nowy-adres/

Pamiętaj, że Redirect dopasowuje początek ścieżki (pełne segmenty) i dokleja resztę. Powyższa reguła przekieruje też /stary-adres/cos na /nowy-adres/cos. Parametry zapytania (?id=12) przechodzą na nowy adres. Jeśli chcesz przekierować dokładnie jeden adres, użyj RedirectMatch z wyrażeniem regularnym:

RedirectMatch 301 ^/stary-adres/?$ https://domena.pl/nowy-adres/

Na stronach, które już korzystają z mod_rewrite (WordPress, PrestaShop i większość CMS-ów), wolę trzymać wszystkie przekierowania w jednym module. Wtedy ten sam efekt daje RewriteRule. Zwróć uwagę, że w .htaccess ścieżka w regule nie zaczyna się od ukośnika:

RewriteEngine On
RewriteRule ^stary-adres/?$ https://domena.pl/nowy-adres/ [R=301,L]

Przekierowanie całej domeny na nową domenę

Przy zmianie domeny każdy adres powinien trafić na swój odpowiednik pod nową domeną, z zachowaniem ścieżki. Ten kod umieszczasz w .htaccess starej domeny:

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?stara-domena\.pl$ [NC]
RewriteRule ^ https://nowa-domena.pl%{REQUEST_URI} [R=301,L]

%{REQUEST_URI} przenosi ścieżkę, a parametry zapytania Apache dokleja domyślnie. Dzięki temu stara-domena.pl/oferta/?utm_source=x trafi na nowa-domena.pl/oferta/?utm_source=x. Jeśli przenosisz tylko część serwisu, np. wersję językową /en/ na osobną domenę, reguła wygląda tak:

RewriteEngine On
RewriteRule ^en(/.*)?$ https://domena.com$1 [R=301,L]

Przekierowanie www na bez www i HTTP na HTTPS

Wersję z www i bez www, a także HTTP i HTTPS, warto obsłużyć jedną regułą, żeby każdy wariant trafiał na adres docelowy jednym skokiem. Wersja docelowa https://domena.pl (bez www):

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://domena.pl%{REQUEST_URI} [R=301,L]

Wersja docelowa https://www.domena.pl (z www):

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^domena\.pl$ [NC]
RewriteRule ^ https://www.domena.pl%{REQUEST_URI} [R=301,L]

Jeśli potrzebujesz samego wymuszenia HTTPS bez zmiany hosta, wystarczy:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Dwie uwagi z praktyki. Po pierwsze, certyfikat SSL musi obejmować obie wersje hosta (z www i bez). Inaczej użytkownik wchodzący na https://www.domena.pl zobaczy ostrzeżenie przeglądarki, zanim przekierowanie w ogóle zadziała. Po drugie, jeśli strona stoi za Cloudflare w trybie SSL „Flexible” albo za innym serwerem proxy, warunek %{HTTPS} off jest zawsze spełniony i reguła wpada w pętlę. W takim układzie przekierowanie na HTTPS ustawiam po stronie Cloudflare (opis niżej).

Zmiana struktury adresów (wyrażenia regularne)

Wyrażenia regularne pozwalają obsłużyć setki adresów jedną regułą. Przykład: WordPress z adresami zawierającymi datę (/2024/08/04/nazwa-wpisu/) przechodzi na adresy z samą nazwą wpisu:

RewriteEngine On
RewriteRule ^[0-9]{4}/[0-9]{2}/[0-9]{2}/(.+)$ https://domena.pl/$1 [R=301,L]

Przykład drugi: stara strona miała adresy z końcówką .html, a nowe adresy obsługuje CMS bez rozszerzenia:

RewriteEngine On
RewriteRule ^(.+)\.html$ https://domena.pl/$1 [R=301,L]

Tę drugą regułę stosuj tylko wtedy, gdy pod adresami z .html nie ma już fizycznych plików, z których serwer korzysta. Inaczej powstanie pętla.

Najważniejsze flagi RewriteRule

FlagaCo robi
R=301Zwraca przekierowanie z kodem 301. Samo R bez numeru oznacza 302.
LKończy przetwarzanie reguł po dopasowaniu. Przy przekierowaniach używaj zawsze razem z R.
NCDopasowanie bez rozróżniania wielkości liter.
QSADokleja oryginalne parametry zapytania, gdy w adresie docelowym podajesz własne parametry.
QSDUsuwa parametry zapytania z adresu docelowego (Apache 2.4+).
NEWyłącza kodowanie znaków specjalnych, np. gdy przekierowujesz na kotwicę #sekcja.

Jeśli chcesz zwrócić informację, że strona zniknęła bez następcy, nie rób przekierowania, tylko zwróć kod 410, np. Redirect gone /stara-promocja/. Więcej o tym w artykule o kodach odpowiedzi 4XX.

Przekierowanie 301 w Nginx

Nginx nie czyta plików .htaccess. Przekierowania dodajesz w konfiguracji bloku server, a potem sprawdzasz składnię i przeładowujesz serwer: nginx -t && systemctl reload nginx. Na hostingu współdzielonym zwykle nie masz dostępu do tych plików. Wtedy zostaje panel hostingu, .htaccess (jeśli za Nginx pracuje Apache) albo przekierowanie w CMS-ie. Nie wiesz, na czym stoi Twoja strona? Różnice opisałem w porównaniu Apache, Nginx i LiteSpeed.

Pojedynczy adres

location = /stary-adres/ {
    return 301 https://domena.pl/nowy-adres/$is_args$args;
}

location = dopasowuje dokładnie ten jeden adres. $is_args$args przenosi parametry zapytania. Bez tego return je gubi.

HTTPS i wersja bez www jednym skokiem

# HTTP (z www i bez) -> https://domena.pl
server {
    listen 80;
    listen [::]:80;
    server_name domena.pl www.domena.pl;
    return 301 https://domena.pl$request_uri;
}

# HTTPS z www -> https://domena.pl
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name www.domena.pl;
    ssl_certificate     /etc/letsencrypt/live/domena.pl/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domena.pl/privkey.pem;
    return 301 https://domena.pl$request_uri;
}

# Właściwa strona
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name domena.pl;
    ssl_certificate     /etc/letsencrypt/live/domena.pl/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/domena.pl/privkey.pem;
    # ... reszta konfiguracji
}

Zmienna $request_uri zawiera ścieżkę razem z parametrami, więc nic nie ginie. Zwróć uwagę, że przekierowanie z HTTP celuje od razu w https://domena.pl, a nie w $scheme://. Dzięki temu http://www.domena.pl nie przechodzi przez pośredni adres. Przy zmianie domeny w server_name wpisujesz starą domenę, a w return nową.

Przekierowanie wielu adresów według wzorca

location ~ "^/[0-9]{4}/[0-9]{2}/[0-9]{2}/(.+)$" {
    return 301 https://domena.pl/$1$is_args$args;
}

Wyrażenie zawierające nawiasy klamrowe {} musi być w cudzysłowie, inaczej Nginx zgłosi błąd składni. Przy dużej liczbie pojedynczych przekierowań (np. setki adresów po migracji sklepu) lepiej sprawdza się dyrektywa map niż setki bloków location.

Przekierowanie 301 w PHP

W PHP przekierowanie robisz funkcją header(). Ważna pułapka: sam nagłówek Location powoduje, że PHP wysyła kod 302. Kod 301 trzeba podać jawnie w trzecim argumencie:

<?php
header('Location: https://domena.pl/nowy-adres/', true, 301);
exit;

header() musi zostać wywołane, zanim skrypt wyśle jakąkolwiek treść (nawet pustą linię przed <?php). Po nim zawsze daję exit, żeby reszta skryptu się nie wykonała.

Przekierowanie 301 w WordPressie

W WordPressie masz trzy drogi, od najprostszej:

  • Zmiana slugu wpisu. Gdy zmieniasz adres opublikowanego wpisu, WordPress zapamiętuje stary slug i sam przekierowuje go kodem 301. Działa to dla wpisów i innych niehierarchicznych typów treści, ale nie dla stron (typ „Strona” jest hierarchiczny). Po zmianie adresu strony przekierowanie musisz dodać sam, tak samo jak przy zmianie struktury bezpośrednich odnośników, kategorii czy domeny.
  • Wtyczka Redirection (darmowa, ponad 2 mln instalacji). W menu Narzędzia → Redirection dodajesz adres źródłowy, docelowy i kod 301. Wtyczka obsługuje wyrażenia regularne, loguje błędy 404 i potrafi wyeksportować reguły do formatu .htaccess lub Nginx. Menedżer przekierowań ma też Yoast SEO, ale tylko w wersji Premium.
  • Własny kod w motywie potomnym lub wtyczce typu mu-plugin, gdy przekierowań jest kilka i nie chcesz kolejnej wtyczki.
<?php
add_action( 'template_redirect', function () {
    $path = trim( (string) wp_parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ), '/' );

    if ( 'stary-adres' === $path ) {
        wp_safe_redirect( home_url( '/nowy-adres/' ), 301 );
        exit;
    }
} );

Funkcje wp_redirect() i wp_safe_redirect() domyślnie wysyłają kod 302, dlatego 301 trzeba podać jawnie. Nie kończą też działania skryptu, więc po nich zawsze jest exit.

Przekierowanie 301 w Cloudflare

Jeśli domena działa przez Cloudflare, przekierowanie możesz ustawić na brzegu sieci, zanim żądanie dotrze do serwera. Warunek: rekord DNS musi być proxowany (pomarańczowa chmurka).

  • Redirect Rules (Single Redirects) – reguły dla jednej domeny, także dynamiczne z symbolem wieloznacznym *. Tworzysz je w Rules → Overview → Create rule → Redirect Rule. Przykład www → bez www: wzorzec https://www.*, adres docelowy https://${1}, kod 301, zaznaczone Preserve query string.
  • Bulk Redirects – listy statycznych par „stary adres → nowy adres” na poziomie konta, także dla wielu domen. Nie obsługują wyrażeń regularnych, ale świetnie sprawdzają się przy migracji z gotową mapą adresów z arkusza (import CSV).
  • Always Use HTTPS – przełącznik w SSL/TLS → Edge Certificates, który przekierowuje cały ruch HTTP na HTTPS.

Jeśli przekierowania ustawiasz w Cloudflare, nie powielaj ich na serwerze. Przy trybie SSL „Flexible” Cloudflare łączy się z serwerem po HTTP, a serwer wymuszający HTTPS odsyła go z powrotem. Efekt to błąd ERR_TOO_MANY_REDIRECTS. Rozwiązaniem jest certyfikat na serwerze i tryb „Full (strict)”.

Przekierowanie bez dostępu do serwera: meta refresh i JavaScript

Gdy nie masz żadnego wpływu na serwer (np. prosta strona na hostingu statycznym), zostają przekierowania po stronie przeglądarki. To nie są przekierowania HTTP 301, ale Google je rozpoznaje. Natychmiastowy meta refresh (content="0; …") traktuje jak przekierowanie stałe, a opóźniony (np. po 5 sekundach) jak tymczasowe. JavaScript Google zaleca tylko wtedy, gdy nie da się zrobić ani przekierowania na serwerze, ani meta refresh, bo wymaga wyrenderowania strony.

<meta http-equiv="refresh" content="0; url=https://domena.pl/nowy-adres/">
<script>
  window.location.href = "https://domena.pl/nowy-adres/";
</script>

Najczęstsze błędy przy przekierowaniach 301

Łańcuchy przekierowań

A → B → C → D zamiast od razu A → D. Każdy skok to dodatkowe opóźnienie dla użytkownika i dodatkowe żądanie dla robota. Googlebot domyślnie podąża za maksymalnie 10 skokami, ale Google zaleca kierowanie od razu na adres docelowy, a jeśli się nie da, to łańcuch najlepiej nie dłuższy niż 3 skoki (i na pewno krótszy niż 5). Łańcuchy powstają najczęściej, gdy osobno przekierowujesz HTTP → HTTPS i www → bez www albo dokładasz nowe reguły przy kolejnych migracjach i nie aktualizujesz starych.

Pętle przekierowań

Adres przekierowuje sam na siebie albo dwa adresy na siebie nawzajem. Przeglądarka pokazuje wtedy błąd „zbyt wiele przekierowań”. Typowe przyczyny to konflikt reguł w .htaccess i we wtyczce, sprzeczne ustawienia adresu witryny w WordPressie (z www i bez) oraz wspomniany tryb „Flexible” w Cloudflare.

302 zamiast 301

Zmiana jest trwała, a serwer odpowiada kodem 302. Najczęstsze źródła: header('Location: ...') w PHP bez kodu, wp_redirect() bez drugiego argumentu, flaga [R] bez =301 i dyrektywa Redirect bez kodu w .htaccess.

Przekierowanie wszystkiego na stronę główną

Przy migracji kusi jedna reguła „wszystko na /”. Google ostrzega, że masowe przekierowanie wielu starych adresów na jedną niezwiązaną stronę, np. główną, może zostać potraktowane jak soft 404. Wtedy sygnały ze starych podstron po prostu przepadają. Każdy ważny adres przekieruj na tematyczny odpowiednik. Jeśli odpowiednika nie ma, zwróć 404 lub 410.

Inne błędy, które często widzę

  • Linki wewnętrzne, menu, mapa witryny i tagi canonical dalej wskazują stare adresy.
  • Przekierowania usunięte po kilku tygodniach, bo „Google już wie”. Utrzymuj je minimum rok.
  • Reguła gubi ścieżkę lub parametry zapytania (np. return 301 https://domena.pl; zamiast z $request_uri).
  • Przekierowanie zasobów, które powinny zostać, np. robots.txt czy plików mapy witryny na nowej domenie.

Takie problemy wychodzą zwykle dopiero przy crawlu całego serwisu. Jeśli planujesz migrację albo podejrzewasz, że przekierowania zjadają Ci ruch, sprawdzam to w ramach audytu SEO.

Jak sprawdzić przekierowanie 301

curl w terminalu

Najszybszy i najbardziej wiarygodny test. curl -I pobiera same nagłówki i nie podąża za przekierowaniem, więc widzisz dokładnie, co zwraca serwer:

curl -I http://www.domena.pl/stary-adres/

Oczekujesz kodu 301 i nagłówka Location z docelowym adresem. Dodanie -L (curl -IL) pokaże cały łańcuch aż do strony docelowej. Jeśli widzisz więcej niż jeden kod 3xx, masz łańcuch. Wersje domeny sprawdzam jednym poleceniem i każda z nich powinna jednym skokiem trafić na ten sam adres:

for u in http://domena.pl http://www.domena.pl https://www.domena.pl https://domena.pl; do
  curl -s -o /dev/null -w "%{url_effective} -> %{http_code} %{redirect_url}\n" "$u/"
done

Narzędzia deweloperskie przeglądarki

F12 → zakładka Network (Sieć), zaznacz Preserve log (Zachowaj dziennik) i wejdź na stary adres. W kolumnie Status zobaczysz 301 i kolejne żądanie. Przeglądarki zapamiętują przekierowania 301 na długo, więc testuj w oknie incognito albo z wyłączoną pamięcią podręczną. Inaczej możesz oglądać stare przekierowanie, którego na serwerze już nie ma.

Narzędzia online i crawlery

  • httpstatus.io i Redirect Checker – pokazują kod i całą ścieżkę przekierowań, także dla wielu adresów naraz.
  • Screaming Frog SEO Spider – po crawlu całej strony filtr Response Codes → Redirection (3xx) i raport łańcuchów przekierowań. Przy migracji wrzucam do niego listę starych adresów w trybie List i sprawdzam, czy każdy kończy się kodem 200 na właściwej stronie.
  • Własny skrypt – przy kilku tysiącach adresów szybciej sprawdzisz je sam. Gotowy przykład opisałem w tekście o masowym sprawdzaniu kodów odpowiedzi w Pythonie.

Google Search Console

Raport Indeksowanie stron w Google Search Console ze statusem Strona zawiera przekierowanie

W Google Search Console wklej stary adres do narzędzia Sprawdzenie adresu URL. Zobaczysz, czy Google wie o przekierowaniu i który adres uznał za kanoniczny. W raporcie Indeksowanie → Strony przekierowane adresy trafiają do grupy „Strona zawiera przekierowanie”. To normalne i nie jest błędem, o ile są tam tylko adresy, które faktycznie miały zostać przekierowane. Po migracji prześlij nową mapę witryny i przez kilka tygodni obserwuj raport „Skuteczność” dla starych i nowych adresów.

FAQ – przekierowania 301

Czym różni się przekierowanie 301 od 302?

301 oznacza zmianę trwałą: Google z czasem pokazuje w wynikach nowy adres i przenosi na niego sygnały. 302 oznacza zmianę tymczasową: Google podąża za przekierowaniem, ale w wynikach zwykle zostawia stary adres. Technicznie konfigurujesz je tak samo, różni się tylko liczba w regule.

Czy przekierowanie 301 przenosi „moc SEO” na nowy adres?

Tak. Przy przekierowaniu stałym Google traktuje adres docelowy jako kanoniczny i konsoliduje na nim sygnały, w tym linki prowadzące do starego adresu. Warunek: nowa strona musi odpowiadać treścią starej. Przekierowanie na niezwiązaną stronę może zostać potraktowane jak soft 404.

Jak długo utrzymywać przekierowanie 301?

Google zaleca co najmniej rok. W praktyce zostawiam przekierowania bezterminowo, bo stare linki zewnętrzne, zakładki i wyniki w innych wyszukiwarkach żyją znacznie dłużej.

Po jakim czasie Google uwzględni przekierowanie?

Dopiero gdy robot ponownie odwiedzi stary adres. Na często odwiedzanych stronach trwa to dni, na rzadko odwiedzanych tygodnie. Przyspieszysz to mapą witryny z nowymi adresami i dobrym linkowaniem wewnętrznym. Więcej o tym w tekście o crawl budget.

Czy przekierowanie 301 można cofnąć?

Na serwerze tak, wystarczy usunąć regułę. Przeglądarki, które już odwiedziły stary adres, mogą jednak przez długi czas pamiętać przekierowanie z pamięci podręcznej. Dlatego przy zmianach, których nie jesteś pewien, zacznij od 302 i zmień je na 301, gdy decyzja jest ostateczna.

Czy reguły z .htaccess zadziałają na serwerze Nginx?

Nie. Nginx ignoruje pliki .htaccess, więc reguły trzeba przepisać na składnię Nginx (przykłady wyżej) albo przenieść do wtyczki lub Cloudflare. Wyjątkiem są hostingi, na których Nginx działa tylko jako proxy przed Apache. Tam .htaccess nadal działa.

Przekierowania to jeden z tych elementów technicznego SEO, które przy zmianach na stronie decydują o tym, czy zachowasz wypracowany ruch. Jeśli przygotowujesz migrację, zmianę domeny albo przebudowę struktury adresów, mogę przygotować mapę przekierowań i sprawdzić wdrożenie w ramach optymalizacji strony.

Tomasz Stopka

Tomasz Stopka

Specjalista SEO od 2008 roku · autor książki „Content Marketing”

Pracowałem w agencjach, w portalu Onet i na własny rachunek jako SEMURAI. W Akademii dzielę się tym, co sprawdziło się w praktyce – konkretnie i bez ściemy.

Czytaj także