Přesměrování 301 je odpověď serveru, která prohlížeči i vyhledávacímu robotu říká: stránka se přestěhovala natrvalo, tady je její nová adresa. Od ostatních způsobů, jak návštěvníka poslat dál, se liší tím, že do indexu přenáší nejen adresu, ale i nasbíranou váhu odkazů. Níže jsou hotová pravidla pro .htaccess, jejich protějšky pro nginx a rozbor chyb, kvůli kterým stěhování stojí web návštěvnost.
Jak to funguje
Server odpoví na požadavek kódem 301 a hlavičkou Location s novou adresou. Prohlížeč tam okamžitě přejde, obvykle bez povšimnutí návštěvníka, a skok si uloží do mezipaměti. Vyhledávač udělá totéž: v indexu nahradí starou URL novou a předá jí váhu odkazů.
Rozdíl mezi kódy je důležitý a stojí peníze:
| Kód | Co znamená | Kdy použít |
|---|---|---|
| 301 | Přestěhováno natrvalo | Změna domény, adresy stránky, sloučení zrcadel, přechod na HTTPS |
| 302 | Dočasně | Akce na pár týdnů, údržba, A/B test |
| 307 | Dočasně, metoda požadavku zůstává | Totéž, ale pro požadavky POST |
| 308 | Natrvalo, metoda zůstává | Vzácný případ: stěhování API, kde záleží na POST |
| 410 | Trvale odstraněno | Stránka už neexistuje a nemá náhradu |
Zaměnit 301 za 302 je nejdražší chyba v tomto seznamu: u 302 ponechá vyhledávač v indexu starou adresu a váhu nepředá.
Pravidla pro .htaccess
Všechny příklady počítají s Apache a zapnutým mod_rewrite. Blok pravidel patří na začátek souboru .htaccess v kořeni webu — před pravidla CMS, jinak požadavek zachytí WordPress dřív.
RewriteEngine On
RewriteBase /
Jedna stránka na druhou
# jednoduchá varianta
Redirect 301 /old-page/ https://site.com/new-page/
# totéž přes mod_rewrite, pokud na něm běží i ostatní pravidla
RewriteRule ^old-page/?$ https://site.com/new-page/ [R=301,L]
Sloučení zrcadel: z www na bez www
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]
Opačný případ, když je hlavním zrcadlem doména s www:
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}/$1 [R=301,L]
Přechod na HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
Za Cloudflare nebo jiným proxy podmínka %{HTTPS} nezabere — požadavek dorazí na server už po HTTP. Tam se kontroluje hlavička:
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
HTTPS a bez www jedním pravidlem
Hlavní trik této části: nedávat dvě pravidla za sebou, jinak vznikne řetězec dvou skoků.
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} ^www.(.+)$ [NC]
RewriteRule ^(.*)$ https://site.com/$1 [R=301,L]
Lomítko na konci adresy
# přidat lomítko
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !.[a-zA-Z0-9]{1,5}$
RewriteCond %{REQUEST_URI} !/$
RewriteRule ^(.*)$ /$1/ [R=301,L]
# odebrat lomítko
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]
Podmínky s !-f a !-d tu nejsou formalita: bez nich začne pravidlo přepisovat i adresy obrázků a existujících složek.
Stěhování na novou doménu
# se zachováním adres stránek — tak se to má dělat
RewriteCond %{HTTP_HOST} ^(www.)?old-site.com$ [NC]
RewriteRule ^(.*)$ https://new-site.com/$1 [R=301,L]
# všechno na úvodní stránku — jen když má nový web úplně jinou strukturu
RewriteRule ^(.*)$ https://new-site.com/ [R=301,L]
Druhou variantu vyhledávače často berou jako „soft 404“ a váhu nepředají. Mapujte adresu na adresu všude, kde to jde, a na úvodní stránku posílejte jen to, co náhradu nemá.
Sekce na sekci a adresy s parametry
# /blog/clanek/ → /news/clanek/
RewriteRule ^blog/(.*)$ /news/$1 [R=301,L]
# ?id=12 → /catalog/sofa/
RewriteCond %{QUERY_STRING} (^|&)id=12(&|$)
RewriteRule ^index.php$ /catalog/sofa/? [R=301,L]
Otazník na konci cíle zahodí původní řetězec parametrů — bez něj se přilepí k nové adrese.
Totéž na nginx
nginx žádný .htaccess nemá: pravidla žijí v konfiguraci serveru a projeví se po nginx -t a znovunačtení.
server {
listen 80;
server_name www.site.com site.com;
return 301 https://site.com$request_uri;
}
# jedna stránka na druhou
location = /old-page/ {
return 301 https://site.com/new-page/;
}
# sekce na sekci
rewrite ^/blog/(.*)$ /news/$1 permanent;
Konstrukce return 301 je rychlejší než rewrite a čte se jednoznačně, proto se u jednoduchých případů sahá právě po ní.
Časté chyby
- Řetězec přesměrování. www → bez www → https → lomítko: čtyři požadavky místo jednoho. Spojte podmínky do jediného pravidla.
- Smyčka. Pravidlo posílá stránku samu na sebe a prohlížeč ukáže
ERR_TOO_MANY_REDIRECTS. Obvyklou příčinou je přesměrování na HTTPS za proxy psané přes%{HTTPS}. - 302 místo 301. Stěhování proběhlo, ale váha zůstala na staré adrese.
- Všechno na úvodní stránku. Hromadné přesměrování stovek stránek do kořene čte vyhledávač jako skrytou 404.
- Pravidla až za blokem CMS. V
.htaccesszachytí požadavek nejdřív WordPress a vaše pravidlo se neuplatní: dejte svůj blok výš. - Přesměrování místo canonical. Pokud lidé potřebují obě stránky a duplikuje se jen obsah, patří tam
rel="canonical", ne 301. - Zapomenuté interní odkazy. Po stěhování musí odkazy uvnitř webu mířit rovnou na novou adresu, jinak jde každý klik přes přesměrování.
Jak to ověřit
Nejrychleji v terminálu. Přepínač -I žádá jen hlavičky, -L jde řetězcem až na konec:
curl -sIL https://site.com/old-page/ | grep -E "HTTP/|Location"
Správná odpověď vypadá takto: jedno HTTP/1.1 301, jedna Location a potom HTTP/2 200. Dvě a více 301 za sebou jsou řetězec, který je třeba srazit do jednoho. V Search Console totéž ukáže report „Indexování stránek“, v prohlížeči záložka Network se zapnutým „Preserve log“.
Po velkém stěhování ověřte vzorek dvou až tří desítek adres: úvodní stránku, kategorie, karty produktů, adresy s parametry a adresy z předních míst ve vyhledávání.
Stručně to hlavní
301 pro trvalé stěhování, 302 pro dočasné, 410 pro to, co už není. Píše se jedno pravidlo, které vede rovnou na cílovou adresu, bez mezikroků. A ověřovat je třeba vždy — curl -sIL odpoví během vteřiny.
Pokud je stěhování velké — nová doména, sloučení webů, přechod na HTTPS s přestavbou adres — napište nám: sestavíme mapu shody a přestěhujeme web tak, aby návštěvnost zůstala.




