Przekierowania 301 w .htaccess – gdzie je dodać, żeby WordPress ich nie nadpisał?
Przekierowanie 301 w pliku .htaccess pozwala trwale przenieść użytkownika i roboty wyszukiwarek ze starego adresu URL na nowy. W WordPressie takie przekierowania bardzo często dodaje się bezpośrednio w pliku .htaccess, ale trzeba wiedzieć, gdzie je umieścić, aby nie zostały nadpisane przez system i żeby działały przed standardowymi regułami WordPressa. To drobny szczegół techniczny, który ma duże znaczenie dla SEO, indeksacji i porządku w strukturze adresów.
Przekierowania 301 są przydatne wtedy, gdy zmieniasz adres podstrony, usuwasz starą treść, łączysz kilka wpisów w jeden, poprawiasz strukturę adresów URL albo przenosisz treści na nową lokalizację. Dzięki nim użytkownik, który wejdzie na stary adres, automatycznie trafi na nowy. Jednocześnie wyszukiwarka otrzymuje sygnał, że zmiana jest trwała i że nowy adres powinien zastąpić stary w wynikach wyszukiwania.
W przypadku WordPressa najważniejsza zasada brzmi: własnych przekierowań nie dodajemy między komentarzami # BEGIN WordPress i # END WordPress. Ten fragment jest generowany automatycznie przez WordPressa i może zostać nadpisany, na przykład po zapisaniu ustawień bezpośrednich odnośników.
Gdzie dodać przekierowania 301 w pliku .htaccess WordPressa?
Najbezpieczniej dodać własne reguły przekierowań nad blokiem WordPressa, czyli przed fragmentem zaczynającym się od:
# BEGIN WordPress
i kończącym się na:
# END WordPress
Dzięki temu własne przekierowania zostaną wykonane wcześniej niż standardowe reguły WordPressa. Ma to znaczenie, ponieważ WordPress w swoim bloku przechwytuje większość adresów i kieruje je do pliku index.php. Jeśli przekierowanie znajdzie się za późno albo w nieodpowiednim miejscu, może nie zadziałać tak, jak powinno.
Przykładowy układ pliku .htaccess może wyglądać tak:
# BEGIN Custom Redirects
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^stary-adres/?$ https://nazwadomeny.pl/nowy-adres/ [R=301,L]
</IfModule>
# END Custom Redirects
# BEGIN WordPress
# Dyrektywy zawarte między „BEGIN WordPress” oraz „END WordPress” są generowane dynamicznie i powinny być modyfikowane tylko za pomocą
# filtrów WordPressa. Zmiany dokonane bezpośrednio tutaj będą nadpisywane.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
W tym przykładzie własne przekierowanie znajduje się nad blokiem WordPressa. To dobre miejsce, ponieważ WordPress nie powinien nadpisać tego fragmentu podczas zapisywania ustawień bezpośrednich odnośników. Dodatkowo reguła przekierowania zostanie sprawdzona zanim WordPress przejmie obsługę adresu.
Komentarze # BEGIN Custom Redirects i # END Custom Redirects nie są obowiązkowe, ale warto je stosować. Pomagają utrzymać porządek w pliku i od razu pokazują, gdzie znajdują się własne przekierowania.
Jak działa RewriteRule w przekierowaniu 301?
Podstawowa reguła przekierowania w .htaccess może wyglądać tak:
RewriteRule ^stary-adres/?$ https://nazwadomeny.pl/nowy-adres/ [R=301,L]
Ta jedna linia mówi serwerowi, że adres:
https://nazwadomeny.pl/stary-adres/
ma zostać trwale przekierowany na:
https://nazwadomeny.pl/nowy-adres/
Warto rozbić tę regułę na części, bo wtedy łatwiej zrozumieć, co właściwie dzieje się w pliku .htaccess.
Fragment:
^stary-adres/?$
oznacza wzorzec starego adresu. Znak ^ wskazuje początek ścieżki, a $ jej koniec. Dzięki temu reguła dotyczy dokładnie wskazanego adresu, a nie przypadkowych adresów zawierających ten sam fragment tekstu.
Element:
/?
oznacza, że końcowy ukośnik jest opcjonalny. Dzięki temu przekierowanie zadziała zarówno dla:
/stary-adres
jak i dla:
/stary-adres/
Docelowy adres:
https://nazwadomeny.pl/nowy-adres/
wskazuje, gdzie użytkownik ma zostać przeniesiony. Może to być pełny adres URL z domeną albo ścieżka względna, jeśli przekierowanie odbywa się w obrębie tej samej domeny.
Końcówka:
[R=301,L]
określa typ przekierowania i sposób dalszego przetwarzania reguł. R=301 oznacza przekierowanie stałe, a L informuje serwer, że po dopasowaniu tej reguły ma zakończyć przetwarzanie kolejnych reguł w tym bloku.
Czy w starej ścieżce dodawać ukośnik na początku?
W pliku .htaccess przy RewriteRule nie dodaje się ukośnika na początku starej ścieżki. To częsty błąd.
Poprawnie:
RewriteRule ^stary-adres/?$ https://nazwadomeny.pl/nowy-adres/ [R=301,L]
Niepoprawnie:
RewriteRule ^/stary-adres/?$ https://nazwadomeny.pl/nowy-adres/ [R=301,L]
W kontekście .htaccess Apache dopasowuje ścieżkę bez początkowego ukośnika. Dlatego wzorzec ^stary-adres/?$ jest prawidłowy, a ^/stary-adres/?$ może nie zadziałać.
To ważne szczególnie wtedy, gdy dodajesz przekierowania ręcznie i później zastanawiasz się, dlaczego reguła wygląda poprawnie, ale nie działa. Bardzo często problemem jest właśnie niepotrzebny ukośnik na początku starego adresu.
Pełny adres czy ścieżka względna w przekierowaniu?
W przekierowaniu możesz użyć pełnego adresu:
RewriteRule ^stary-adres/?$ https://nazwadomeny.pl/nowy-adres/ [R=301,L]
albo krótszej ścieżki względnej:
RewriteRule ^stary-adres/?$ /nowy-adres/ [R=301,L]
Oba warianty mogą być poprawne. Pełny adres jest czytelny i jednoznaczny, szczególnie gdy chcesz mieć pewność, że przekierowanie prowadzi na konkretną wersję domeny, na przykład z https. Ścieżka względna jest krótsza i wygodna, gdy przekierowanie odbywa się w obrębie tej samej domeny.
W praktyce, jeśli pracujesz na jednej stronie i przekierowujesz tylko stare adresy na nowe adresy w tej samej domenie, możesz używać krótszego zapisu:
RewriteRule ^stary-adres/?$ /nowy-adres/ [R=301,L]
Jeśli jednak porządkujesz adresy po migracji, zmianie domeny albo chcesz jasno określić wersję protokołu i domeny, pełny adres będzie bezpieczniejszy:
RewriteRule ^stary-adres/?$ https://nazwadomeny.pl/nowy-adres/ [R=301,L]
Jak dodać kilka przekierowań 301?
Jeśli masz więcej przekierowań, dodajesz kolejne reguły jedna pod drugą w tym samym własnym bloku nad WordPressem.
Przykład:
# BEGIN Custom Redirects
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^stary-adres/?$ /nowy-adres/ [R=301,L]
RewriteRule ^stara-oferta/?$ /oferta/ [R=301,L]
RewriteRule ^blog/stary-wpis/?$ /blog/nowy-wpis/ [R=301,L]
RewriteRule ^kontakt-stary/?$ /kontakt/ [R=301,L]
</IfModule>
# END Custom Redirects
Każda reguła odpowiada za jedno przekierowanie. Stary adres podajesz jako wzorzec po lewej stronie, a nowy adres jako miejsce docelowe po prawej stronie.
Warto zachować prosty porządek: jedna linia, jedno przekierowanie. Przy kilku lub kilkunastu adresach to wystarczy. Przy większej liczbie przekierowań dobrze prowadzić dodatkową listę w arkuszu albo dokumencie, aby wiedzieć, skąd i dokąd prowadzą poszczególne reguły.
Dlaczego nie edytować reguł między BEGIN WordPress i END WordPress?
Blok WordPressa w .htaccess jest generowany automatycznie. Zazwyczaj wygląda podobnie do tego:
# BEGIN WordPress
# Dyrektywy zawarte między „BEGIN WordPress” oraz „END WordPress” są generowane dynamicznie i powinny być modyfikowane tylko za pomocą
# filtrów WordPressa. Zmiany dokonane bezpośrednio tutaj będą nadpisywane.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Sam WordPress informuje w komentarzu, że zmiany dokonane bezpośrednio w tym miejscu mogą zostać nadpisane. Może się to stać po zmianie ustawień bezpośrednich odnośników, aktualizacji, migracji strony, działaniu niektórych wtyczek albo przy odtwarzaniu strony z kopii.
Dlatego własne przekierowania powinny znaleźć się poza tym blokiem. Najczęściej nad nim. Dzięki temu masz większą kontrolę nad plikiem i nie ryzykujesz, że ręcznie dodane przekierowania znikną po jakiejś operacji w panelu WordPressa.
Kiedy używać przekierowania 301, a kiedy 302?
Przekierowanie 301 oznacza przekierowanie stałe. Używaj go wtedy, gdy stary adres ma zostać zastąpiony nowym na stałe. To najczęstszy wybór przy zmianie slugów, porządkowaniu adresów, usuwaniu starych podstron i migracji treści.
Przekierowanie 302 oznacza przekierowanie tymczasowe. Warto użyć go na etapie testów albo wtedy, gdy przeniesienie jest chwilowe. Przykład testowej reguły:
RewriteRule ^stary-adres/?$ /nowy-adres/ [R=302,L]
Po sprawdzeniu, że wszystko działa poprawnie, można zmienić 302 na 301:
RewriteRule ^stary-adres/?$ /nowy-adres/ [R=301,L]
To rozsądna praktyka, bo przekierowania 301 mogą być zapamiętywane przez przeglądarki i cache. Jeśli pomylisz adres docelowy, a przeglądarka zapamięta błędne przekierowanie, późniejsze testowanie może być irytujące. Dlatego przy świeżych zmianach warto najpierw sprawdzić wszystko jako 302, a dopiero potem ustawić 301.
Czy przekierowanie 301 przenosi parametry z adresu URL?
Standardowo przy regułach RewriteRule parametry zapytania mogą zostać zachowane. Chodzi o fragmenty adresu po znaku zapytania, na przykład:
?utm_source=google
Jeśli użytkownik wejdzie na:
/stary-adres/?utm_source=google
to po przekierowaniu parametr może przejść dalej na nowy adres.
W wielu przypadkach jest to w porządku, szczególnie jeśli zależy Ci na zachowaniu parametrów kampanii. Jeżeli jednak chcesz wyczyścić parametry przy przekierowaniu, możesz użyć flagi QSD, czyli Query String Discard.
Przykład:
RewriteRule ^stary-adres/?$ /nowy-adres/ [R=301,L,QSD]
Taka reguła przekieruje użytkownika na nowy adres bez przenoszenia parametrów zapytania.
Nie zawsze trzeba to stosować. Przy zwykłych przekierowaniach SEO najczęściej wystarczy standardowy zapis:
RewriteRule ^stary-adres/?$ /nowy-adres/ [R=301,L]
Redirect 301 czy RewriteRule?
W .htaccess można spotkać też prostszy zapis:
Redirect 301 /stary-adres/ https://example.pl/nowy-adres/
To również może działać, ale w WordPressie wygodniej i czytelniej trzymać przekierowania w mod_rewrite, szczególnie jeśli już korzystasz z bloku:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule daje większą elastyczność. Możesz łatwiej obsłużyć opcjonalny końcowy ukośnik, bardziej złożone wzorce, katalogi, parametry i dodatkowe warunki. Przy prostym przekierowaniu jednej podstrony oba podejścia mogą być poprawne, ale mieszanie wielu metod w jednym pliku potrafi po czasie zrobić bałagan.
Jeśli strona działa na WordPressie i standardowy plik .htaccess już korzysta z mod_rewrite, praktycznym rozwiązaniem jest dodawanie własnych reguł właśnie przez RewriteRule.
Najczęstsze błędy przy przekierowaniach 301 w .htaccess
Przy ręcznym dodawaniu przekierowań w WordPressie najczęściej problemy wynikają z drobnych pomyłek. Warto uważać szczególnie na kilka rzeczy:
- dodanie własnych reguł wewnątrz bloku
# BEGIN WordPressi# END WordPress, - użycie ukośnika na początku starej ścieżki w
RewriteRule, - literówka w starym lub nowym adresie,
- brak testu po zapisaniu pliku,
- utworzenie pętli przekierowań, gdy stary adres kieruje na nowy, a nowy znowu wraca na stary,
- testowanie od razu na
301, bez wcześniejszego sprawdzenia na302, - przekierowanie na adres, który sam zwraca błąd 404 albo kolejne niepotrzebne przekierowanie.
Najprostsza dobra praktyka jest taka: najpierw zrób kopię pliku .htaccess, potem dodaj regułę, sprawdź działanie, a dopiero na końcu zostaw przekierowanie jako stałe 301.
Jak sprawdzić, czy przekierowanie działa?
Po zapisaniu pliku .htaccess warto od razu sprawdzić stary adres w przeglądarce. Najlepiej zrobić to w trybie incognito albo w innej przeglądarce, aby uniknąć wpływu cache. Możesz też użyć narzędzia do sprawdzania nagłówków HTTP lub redirect checker, które pokaże, czy serwer zwraca kod 301 i na jaki adres prowadzi przekierowanie.
Poprawny efekt powinien być taki:
/stary-adres/ -> 301 -> /nowy-adres/
Jeśli widzisz kilka przekierowań po drodze, na przykład z HTTP na HTTPS, z wersji bez www na www, a dopiero potem na nowy adres, warto sprawdzić, czy da się to uprościć. Dla SEO i wydajności najlepiej, gdy przekierowanie prowadzi możliwie bezpośrednio do adresu docelowego.
Jeżeli po zapisaniu pliku strona przestanie działać i pojawi się błąd serwera, najczęściej oznacza to literówkę lub błąd składni w .htaccess. Wtedy należy cofnąć ostatnią zmianę albo przywrócić wcześniejszą kopię pliku.
Przykładowy gotowy szablon przekierowań dla WordPressa
Poniżej znajduje się prosty szablon, który można wykorzystać jako punkt wyjścia. Własne przekierowania znajdują się nad blokiem WordPressa i są oddzielone komentarzami.
# BEGIN Custom Redirects
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^stary-adres/?$ https://nazwadomeny.pl/nowy-adres/ [R=301,L]
RewriteRule ^stara-podstrona/?$ https://nazwadomeny.pl/nowa-podstrona/ [R=301,L]
RewriteRule ^blog/stary-wpis/?$ https://nazwadomeny.pl/blog/nowy-wpis/ [R=301,L]
</IfModule>
# END Custom Redirects
# BEGIN WordPress
# Dyrektywy zawarte między „BEGIN WordPress” oraz „END WordPress” są generowane dynamicznie i powinny być modyfikowane tylko za pomocą
# filtrów WordPressa. Zmiany dokonane bezpośrednio tutaj będą nadpisywane.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
To dobry, prosty układ do codziennej pracy z WordPressem. Własne reguły są wyżej, więc mają pierwszeństwo. Nie znajdują się w części generowanej przez WordPressa, więc nie powinny zostać nadpisane. Każde kolejne przekierowanie można dopisać jako osobną linię w bloku Custom Redirects.
Ręczne przekierowania 301 w .htaccess nie są trudne, ale wymagają precyzji. Najważniejsze jest to, aby umieszczać je poza automatycznym blokiem WordPressa, najlepiej nad nim, stosować poprawny zapis starej ścieżki bez początkowego ukośnika i po każdej zmianie sprawdzić efekt. Dzięki temu można spokojnie porządkować stare adresy, poprawiać strukturę URL i ograniczać ryzyko błędów 404, które negatywnie wpływają zarówno na użytkownika, jak i na widoczność strony w wyszukiwarce.