URL değiştirdiğinde, içerik taşındığında ya da alan adı yenilendiğinde arama motorlarının ve kullanıcıların doğru sayfaya ulaşmasını sağlayan en güvenilir yöntem kalıcı yönlendirmedir. HTTP durum kodları içinde 301, "Bu kaynak kalıcı olarak taşındı" mesajını verir ve bağlantıya aktarılan SEO değerinin büyük bölümünü yeni adrese iletir.
302'yi yanlışlıkla kullanan siteler bunu genellikle geç fark eder — sorun anlık değil, indeksleme döngüsü tamamlandıktan sonra ortaya çıkar. Link equity (bağlantı değeri) tam aktarılmaz; Googlebot, eski URL'yi bir süre daha birincil kayıt olarak tutabilir. Apache tabanlı sunucularda en yaygın kurulum noktası .htaccess dosyasıdır — sunucu yeniden başlatılmasına gerek kalmadan anında aktif olan bu dosyayla karmaşık yönlendirme kuralları bile tek bir yerden yönetilir.
Temel 301 yönlendirme sözdizimi
Tek bir eski URL'yi yeni adresine yönlendirmek için Redirect direktifi yeterlidir:
# Eski sayfa → Yeni sayfa (kalıcı 301)
Redirect 301 /eski-sayfa.html https://www.siteni.com/yeni-sayfa.html
İlk parametre kök dizinden itibaren göreceli yol, ikincisi ise tam URL olmalıdır. Protokol dahil hedef adresi eksiksiz belirt; eksik yazılan hedefler bazı Apache versiyonlarında döngüye neden olur.
Birden fazla sayfayı yönlendirirken her kuralı ayrı satıra yaz. Daha özgül (uzun) URL'leri listenin üstünde tutmak, kural çakışmalarını önler:
Redirect 301 /blog/eski-yazi https://www.siteni.com/blog/yeni-yazi.html
Redirect 301 /urunler/model-a https://www.siteni.com/urunler/model-b.html
Redirect 301 /iletisim.php https://www.siteni.com/iletisim.html
Redirect direktifinin önemli bir sınırı var: sorgu dizelerini (query string) hedef URL'ye otomatik taşımaz. /arama?q=kelime gibi parametreli URL'leri yönlendirirken mod_rewrite kullan; %{QUERY_STRING} değişkeniyle parametreyi yeni adrese ekleyebilirsin.
mod_rewrite ile desen tabanlı yönlendirme
Sabit URL çiftleri yerine bir URL kalıbının tamamını yönlendirmen gerektiğinde mod_rewrite devreye girer. Örneğin /haber/2024/slug formatındaki tüm eski haber URL'lerini blog'a taşımak için:
RewriteEngine On
# /haber/[yil]/[slug] → /blog/[slug]
RewriteRule ^haber/[0-9]{4}/(.+)$ /blog/$1 [R=301,L]
R=301 bayrağı yönlendirmenin kalıcı olduğunu, L bayrağı ise bu kural eşleştiğinde kural listesinin sonlandırılacağını belirtir. L bayrağını unutmak zincirleme kural sorunlarına neden olur.
Daha karmaşık URL yapılarında birden fazla yakalama grubu kullanılabilir. ^kategori/([^/]+)/urun/([^/]+)$ gibi bir pattern, $1 ve $2 değişkenleriyle yeni URL'yi dinamik olarak oluşturmanı sağlar. Kural karmaşıklaştıkça okunabilirlik düşer — her regex bloğunun üstüne ne yaptığını açıklayan kısa bir yorum satırı ekle.
htaccess oluşturmak için kullandığın araç, mod_rewrite kurallarını da doğru sözdizimle üretir; çıktıyı doğrudan .htaccess dosyana ekleyebilirsin.
HTTPS ve WWW yönlendirmeleri
Sitenin tutarlı bir URL üzerinden erişilmesi hem kullanıcı deneyimi hem de indeksleme açısından kritiktir. Bu iki yönlendirmeyi ayrı bloklar hâlinde tanımlamak sorun gidermede kolaylık sağlar.
HTTP'den HTTPS'e zorlama:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
WWW olmayan sürümü, www'ye yönlendirme (ya da tersi — ikisinden yalnızca birini kullan):
# siteni.com → www.siteni.com
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Bu iki kurala dikkat: her ikisini aynı anda aktif edersen sonsuz yönlendirme döngüsü oluşur. Tercihini belirledikten sonra Google Search Console'da da tercih ettiğin sürümü tanımla.
Uzantı ve dizin değişikliklerinde 301
PHP'den statik HTML'e geçiş gibi teknoloji değişikliklerinde tüm eski URL'leri tek tek listelemek yerine desen tabanlı kurallar çok daha verimlidir:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)\.php$ /$1.html [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f koşulu, fiziksel olarak var olan .php dosyalarını etkisiz bırakır; yalnızca bulunamayan eski URL'ler yönlendirilir.
URL sonundaki slash tutarsızlığı da duplicate content kaynağıdır. /hakkimizda ile /hakkimizda/ aynı içeriği servis ediyorsa birini diğerine yönlendir:
# Gerçek dizinlere trailing slash ekle
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*[^/])$ /$1/ [R=301,L]
Desen tabanlı kurallar güçlüdür; ama beklenmedik eşleşmeler üretebilir. /yazarlar/ali-veli gibi bir URL, geniş yazılmış bir pattern içinde istemeden yakalanabilir. Staging ortamında test etme imkânın yoksa önce tek bir URL'yi sabit Redirect kuralıyla doğrula, ardından pattern'e geç. Birkaç onlarca URL için sabit liste hem okunması hem de hata ayıklaması daha kolaydır.
Yaygın hatalar ve çözümleri
Yönlendirme döngüsü en sinsi hata tipidir. Semptom belirgin — ERR_TOO_MANY_REDIRECTS — ama kök neden her zaman açık değildir.
Yönlendirme döngüsü (redirect loop): Tarayıcı ERR_TOO_MANY_REDIRECTS gösteriyorsa kural hedefi kendisini tetikliyor demektir. En sık senaryo: HTTPS kuralı yazılmış, ama SSL sonlandırması CDN veya load balancer'da yapılıyor (bu durumda HTTPS değişkeni sunucuya "off" olarak gelir). Çözüm, X-Forwarded-Proto başlığını da kontrol etmektir:
❌ Yanlış (CDN SSL sonlandırıyorsa):
RewriteCond %{HTTPS} off
RewriteRule ^ https://... [R=301,L]
✓ Doğru:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://... [R=301,L]
Eksik RewriteEngine On: mod_rewrite kullanan her .htaccess bloğunda bu satır zorunludur. Olmadan tüm RewriteRule ve RewriteCond satırları görmezden gelinir.
Büyük/küçük harf duyarlılığı: Linux sunucularda /Blog/Yazi.html ile /blog/yazi.html farklı sayfalardır. Desen eşleşmesinde büyük/küçük harf sorununu önlemek için [NC] (No Case) bayrağını ekle.
Tarayıcı önbelleği gözden kaçan bir tuzaktır. 301 yönlendirmelerini tarayıcı önbelleğe alır; test sırasında hatalı bir kural uygulandıysa ve düzeltildiyse özel sekme aç, önbelleği temizleyerek de doğrulayabilirsin.
Kural listesi büyüdükçe bakım yükü de artar. On-yirmi kuralı geçen .htaccess dosyalarında kural sırası beklenmedik eşleşmelere yol açar — özellikle benzer URL kalıpları aynı blokta bir arada olduğunda. Kuralları işlevlerine göre yorum satırlarıyla grupla; tek bir kural değişikliği için tüm dosyayı taramak zorunda kalmazsın. Sabit URL çiftlerini dinamik regex ile karıştırma: sabit listeler dosyanın üstünde, pattern tabanlı kurallar altta dursun. Bu sıra hem okunabilirliği artırır hem de Apache'nin kural değerlendirme sırasıyla uyumlu olur.
Yönlendirmeleri doğrulama
Kural yazdıktan sonra mutlaka test et. Terminalden HTTP durum kodunu ve hedef URL'yi kontrol etmek için:
# -I: yalnızca başlıklar, -L: yönlendirmeleri takip et
curl -I -L https://www.siteni.com/eski-sayfa.html
Çıktıda önce 301 Moved Permanently, ardından Location: başlığında hedef URL görünmeli. Hedef sayfadan 200 OK dönüyorsa kural doğru çalışıyor demektir. Ara adımda ikinci bir 301 görürsen yönlendirme zinciri var — her atlama, Googlebot'un link equity'yi nasıl aktardığını etkiler ve tarama bütçesini tüketir. Bu durumda aradaki yönlendirmeyi kaldırıp doğrudan nihai URL'ye bağla.
Arama motorlarının yönlendirmeyi algılayıp algılamadığını izlemek için site analiz aracıyla düzenli tarama yapman, sorunları erken yakalamanı sağlar. Daha önce yayımladığımız .htaccess yapılandırma rehberinde direktif hiyerarşisi ve dosya konumu gibi temel konuları bulabilirsin.