WordPress .htaccess Yönlendirme Kuralları: 301'i Doğru Kurmak
Bir URL'yi sıralamanızı kaybetmeden taşıyın: hangi WordPress .htaccess yönlendirme direktifini kullanacağınız, kuralların nereye yazılması gerektiği ve siteye kilitlenmeden nasıl test edileceği.
Yayınlandı
Bir URL’yi taşıyorsunuz ve eskisinin sıralamasını korumasını istiyorsunuz, öyle mi? O zaman .htaccess içinde bir 301’e ihtiyacınız var: WordPress’in silmeyeceği bir yere konmuş, doğru direktifle yazılmış ve WordPress’in gerçekte sunduğu URL’ye yöneltilmiş bir 301. Bu üçünden birini yanlış yaparsanız elinize bir yönlendirme zinciri, bir döngü ya da sizi wp-admin dışında bırakan bir 500 geçer.
Sırasıyla: karar, konum kuralı ve test.
Hangi direktif: Redirect, RedirectMatch mi, RewriteRule mı
Devrede iki Apache modülü var ve bunlar birbirinin yerine geçmez.
Redirect (mod_alias) — bilinen tek bir yoldan tek bir hedefe. İşi gören en basit yol:
Redirect 301 /old-page/ https://example.com/new-page/
Bilmeniz gereken iki davranış var. Tam bir dize üzerinden değil, yol ön eki üzerinden eşleşir; yani /old-page/ aynı zamanda /old-page/anything/ adresini de yakalar ve hedefe /anything/ kısmını ekler. Ayrıca sorgu dizesini otomatik olarak taşır.
RedirectMatch (mod_alias) — çok sayıda URL’yi kapsayan tek bir düzenli ifade. Bütün bir bölümü böyle taşırsınız:
RedirectMatch 301 ^/blog/(.*)$ https://example.com/articles/$1
Yakalama grubu (.*), hedefte $1 olur; böylece /blog/hello-world/ adresi /articles/hello-world/ üzerine iner. Baştaki eğik çizgiye dikkat: mod_alias desenleri URL yolunun tamamıyla eşleşir.
RewriteRule (mod_rewrite) — yönlendirme bir koşula bağlıysa zorunludur: ana makine adı, protokol, sorgu dizesi, kullanıcı aracısı. mod_alias içindeki hiçbir şey bunları sınayamaz.
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
Dizin düzeyindeki bir .htaccess içindeki desende baştaki eğik çizgi kırpılır — burada ^(.*)$, mod_alias örneğinde ise ^/blog/ yazmasının sebebi budur. Bunu karıştırmak, yapıştırılan bir kuralın sessizce hiçbir şey yapmamasının bir numaralı nedenidir.
Varsayılan olarak mod_alias’ı seçin. RewriteRule işine yalnızca bir koşula ihtiyacınız olduğunda girişin. Daha az düzenli ifade, yanlış yapmanın daha az yolu.
Kuralların bulunması gereken yer
Özel yönlendirmeler # BEGIN WordPress satırının üstüne aittir. İçine değil.
# --- custom redirects ---
Redirect 301 /old-page/ https://example.com/new-page/
RedirectMatch 301 ^/blog/(.*)$ https://example.com/articles/$1
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
<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
Birbirinden bağımsız iki sebep:
- WordPress kendi bloğunu yeniden yazar. Ayarlar → Kalıcı Bağlantılar ekranını kaydetmek
flush_rewrite_rules()çağırır; bu da işaretçiler arasındaki her şeyi atıp yeniden üretir. İçeri koyduğunuz bir kural, o ekrana biri bir dahaki sefer dokunduğunda kaybolur — belki aylar sonra, üstelik kimse iki olayı birbirine bağlamadan. - Sırayı kim kazanır, sıra belirler. WordPress bloğu, dosya ya da dizin olmayan her isteği
index.phpdosyasına gönderen bir yakala-tümü kuralıyla biter. Bunun ardına konan birRewriteRuleasla çalışmaz.
Dürüst olmak gerekirse bir komplikasyon var: mod_alias ve mod_rewrite aslında dosya sırasına göre çalışmaz. Apache, mod_alias’ı URL çeviri aşamasında, dizin düzeyindeki mod_rewrite’ı ise daha sonra, fixup aşamasında işler — yani bir Redirect satırı, dosyada onun üstünde görünen bir RewriteRule kuralına karşı üstün gelebilir. Kendinizi örtüşen yollarda ikisine birden ihtiyaç duyarken bulursanız, o yol için tek bir modül seçin ve onun içinde kalın. mod_alias’a karşı mod_rewrite kavgasını ayıklamak, harcanacak bir saate değmez.
Sondaki eğik çizgiler
WordPress’in kendi kanonik yönlendirmesi çoğu kalıcı bağlantıya sonda eğik çizgi ekler. Yani şu:
Redirect 301 /old-page/ https://example.com/new-page
iki sıçrama üretir — sizin 301’iniz eğik çizgisiz URL’ye, ardından WordPress’in kendi 301’i eğik çizgiyi ekler. Zincirler sıralama sinyallerini yine aktarır ama tarama bütçesini harcar ve her ziyaretçiye fazladan bir gidiş-dönüş bindirir.
Önce hedefi bir tarayıcıda açın, adres çubuğunda son hâline yerleştiği hâliyle URL’yi birebir kopyalayın ve onu kullanın. Kalıcı bağlantı yapınız .html ile bitiyorsa ya da sonda eğik çizgi yoksa, ona göre eşleştirin. Burada evrensel bir doğru cevap yok; yalnızca “WordPress ne sunuyorsa onu eşleştir” var.
Kendinizi dışarıda bırakmadan test etmek
.htaccess her istekte okunur. Bir sözdizimi hatası, wp-admin dâhil tüm site için 500 döndürür; dolayısıyla kurtarma yolu, ona ihtiyaç duymadan önce hazır olmalıdır.
Önce dosyayı yedekleyin. SSH üzerinden:
cp /path/to/wordpress/.htaccess /path/to/wordpress/.htaccess.bak
Site 500 verirse, bozuk dosyanın üzerine yedeği geri adlandırın; site anında geri döner. Başka bir pencerede açık duran bir SFTP oturumu bulundurun — site çökmüşken sıfırdan oturum açmaya çalışmak, panik tam orada başlar. Şunu da not edin: apachectl configtest .htaccess dosyasını ayrıştırmaz, dolayısıyla siteniz ölmüşken bile size sağlıklı bir yapılandırma bildirir.
Tarayıcıyla değil, curl ile test edin. Tarayıcılar 301 yanıtlarını sıkı biçimde önbelleğe alır ve size gönül rahatlığıyla dünkü sonucu gösterir:
curl -sI https://example.com/old-page/ | head -n 5
İki şeyi okuyun: durum satırı 301 demeli ve Location: başlığı tam olarak nihai URL olmalı. Zincirin tamamını görmek için takip edin:
curl -sIL https://example.com/old-page/ | grep -E '^(HTTP|Location)'
Birden fazla HTTP/1.1 301 satırı, bir zincir kurduğunuz anlamına gelir. Beşten fazlası bir döngü kurduğunuz anlamına gelir; curl durur ve bunu size söyler.
Emin olamadığınız sürece 302 kullanın. 302 aynı şekilde önbelleğe alınmaz, dolayısıyla bir hata saniyeler içinde geri alınabilir. curl size istediğiniz hedefi gösterdiğinde 301’e geçin. Bunun hiçbir maliyeti yok ve bu yazıdaki diğer tüm alışkanlıklardan daha fazla site kurtardı.
Bir kural hiçbir şey yapmıyor gibi görünüyorsa, Apache’nin dosyayı okuyup okumadığını doğrulayın. Dizinde AllowOverride None varsa Apache .htaccess dosyasını tamamen yok sayar; nginx ise onu zaten hiç dikkate almaz — düzenli ifadeleri ayıklamaya başlamadan önce curl -I ile Server: başlığını kontrol edin. Bloğu Apache sürümünüze ve kurulum yolunuza uygun sözdizimiyle oluşturmak için WordPress .htaccess oluşturucusunu kullanın.
.htaccess’i hiç kullanmamak gereken durumlar
Editörlerin kendi başlarına yönetmesi gereken bir avuç yönlendirme için, kuralları veritabanında saklayan bir yönlendirme eklentisi daha doğru araçtır — barındırma taşımalarından sağ çıkar ve SSH gerektirmez. Bedeli gerçektir: yönlendirmeyi sunmak için php’nin ayağa kalkması gerekir, bu da Apache’nin doğrudan cevap vermesinden yavaştır.
.htaccess dosyasını yapısal ve kalıcı taşımalar için kullanın — alan adı değişikliği, bölüm yeniden adlandırma, https ya da www zorlama. Tek seferlik editöryel yönlendirmeler için eklenti kullanın. İkisini birden kullanmak sorun değil, yeter ki hangi katmanın hangi URL’nin sahibi olduğunu bilin; çünkü iki ayrı yerde tanımlanmış bir yönlendirme, kötü bir öğleden sonrayı bekleyen bir hatadır.
FAQ
Sorular
WordPress .htaccess dosyasında özel yönlendirmeler nereye yazılır?
# BEGIN WordPress satırının üstüne; asla işaretçilerin arasına değil. Permalink ayarları ekranını her kaydeden kişi, WordPress'in o işaretçiler arasındaki her şeyi yeniden üretmesine yol açar, dolayısıyla içeri konan bir kural uyarı vermeden silinir. Konum sıralama açısından da önemlidir: WordPress bloğu, eşleşmeyen istekleri index.php dosyasına gönderen bir yakala-tümü kuralıyla biter.
301 için Redirect mi, RedirectMatch mi, RewriteRule mı kullanmalıyım?
Tek ve bilinen bir yol için Redirect, tek bir desenin çok sayıda URL'yi kapsadığı durumlarda RedirectMatch, yönlendirme ana makine adı, protokol ya da sorgu dizesi gibi bir koşula bağlıysa RewriteRule kullanın. Redirect ve RedirectMatch mod_alias modülünden gelir ve daha basittir. RewriteRule mod_rewrite modülünden gelir ve koşul sınayabilen tek seçenektir.
htaccess yönlendirmem neden yönlendirme döngüsüne giriyor?
Genellikle hedef adres, ziyaretçiyi oraya gönderen kuralla hâlâ eşleşiyordur; kural da sonsuza kadar tekrar tetiklenir. Diğer yaygın sebep, yük dengeleyici ya da CDN arkasında https zorlamaktır: ziyaretçi zaten https üzerindeyken bile sunucu her isteği düz http olarak görür. Bunun yerine X-Forwarded-Proto başlığını sınayın.
WordPress yönlendirmesinde sondaki eğik çizgi önemli mi?
Evet. WordPress'in kanonik yönlendirmesi çoğu kalıcı bağlantıya sonda eğik çizgi ekler, dolayısıyla 301'i eğik çizgisiz bir URL'ye yöneltmek tek sıçrama yerine iki sıçrama üretir. Zincirlenmiş yönlendirmeler sıralama sinyallerini yine aktarır ama tarama bütçesini harcar ve ziyaretçiyi yavaşlatır. WordPress'in gerçekte sunduğu nihai URL'yi, eğik çizgi dâhil, birebir eşleştirin.
Bir htaccess yönlendirmesini sitemi bozmadan nasıl test ederim?
Tarayıcıya güvenmeden önce eski URL'ye karşı curl'ü yalnızca başlık kipinde çalıştırıp durum kodunu ve Location başlığını okuyun. Tarayıcılar 301 yanıtlarını agresif biçimde önbelleğe alır ve size bayat bir sonuç gösterir. Önce çalışan dosyanın bir kopyasını saklayın, çünkü htaccess içindeki bir sözdizimi hatası wp-admin dâhil her sayfada 500 döndürür.
Yönlendirme ekledikten sonra tüm sitem neden 500 hatası verdi?
htaccess içindeki tek bir bozuk direktif, o dizin altındaki her URL'yi, yönetim paneli dâhil, devre dışı bırakır. Yaygın sebepler: kapatılmamış bir IfModule sarmalayıcısı, eksik bir RewriteEngine On satırı ya da tek dosyada karışmış Apache 2.2 ve 2.4 erişim sözdizimi. Eklediğiniz son bloğu kaldırıp sayfayı yeniden yükleyerek doğrulayın.