Ana içeriğe geç

Trailing Slash Yönetimi: URL Sonundaki / Ekleme/Kaldırma

Trailing Slash Yönetimi: URL Sonundaki / Ekleme/Kaldırma - Teknik SEO Rehberi

Trailing slash, URL'nin sonundaki eğik çizgidir: example.com/sayfa/ ile example.com/sayfa farklı string olarak işlenir. Web sunucuları bu iki string için farklı yanıt üretebilir; ürettiğinde de aynı içerik iki URL altında erişilebilir hale gelir. Tek başına küçük bir fark gibi görünür; ama indeksleme davranışını ve canonical sinyal dağılımını doğrudan etkiler.

Aynı sayfa, iki URL

Apache'de bir dizin isteği geldiğinde sunucu, DirectorySlash On yönergesiyle trailing slash olmayan URL'yi otomatik olarak slash'lı versiyona yönlendirir. Apache 2.4 itibarıyla bu yönlendirme 301 döndürür; eski sürümlerde 302 kullanıldığı görülürdü. PHP tabanlı CMS'lerde ise hem /sayfa hem /sayfa/ 200 HTTP durum kodu dönebilir; çünkü uygulama katmanı her ikisini de yakalayıp işler.

İki URL, iki indeks girişi.

Googlebot canonical etiket yokken her iki URL'yi bağımsız kaynak olarak tarar; PageRank sinyalleri ikiye bölünür, iç linkler tutarsız yazılmışsa bölünme oranı artar ve tarama bütçesi her iki URL için ayrı ayrı harcanır. Backlink profili de etkilenir: dışarıdan gelen bağlantıların bir kısmı slash'lı, bir kısmı slash'sız versiyona gelirse, Google her iki sayfanın ayrı otoritesini hesaplar.

Canonical etiket bu sorunu kısmen çözer; ama yönlendirme olmadan çalışan bir canonical, Google'ın "tercih edilen URL" ipucunu alması için ek tarama turu gerektirir. Yönlendirme + canonical birlikte uygulandığında sinyal netliği en yüksek seviyeye ulaşır.

Statik dosyalar için mesele farklıdır. example.com/gorsel.jpg/ isteği Apache'de varsayılan olarak 404 döndürür; çünkü bir dosya "dizin" olarak işlenemez. Trailing slash yönetimi, gerçek dizin yapısı olan URL'lerde kritik hale gelir.

Ekleme mi, kaldırma mı?

İki yaklaşımdan biri seçilir ve site genelinde tutarlı biçimde uygulanır; karma yapı tutarsız canonical sinyaline yol açar. Hangi yaklaşımın seçileceğini belirleyen birkaç değişken vardır.

Trailing slash ekleme şu durumlarda tercih edilir: WordPress, Drupal, Joomla gibi CMS'ler varsayılan olarak slash'lı URL yapısını kullanır ve permalink ayarları buraya göre yapılandırılmıştır. Mevcut backlink profilinin büyük kısmı slash'lı versiyona geliyorsa, kaldırma yönünde yapılan yönlendirme mevcut linki geçersiz kılmaz ama 301 zinciri ekler. Mevcut iç link yapısı zaten slash'lıysa kaldırma tercihiyle tutarsızlık ortaya çıkar.

Trailing slash kaldırma şu durumlarda öne çıkar: React, Next.js veya Nuxt gibi JavaScript framework'leri varsayılan olarak slash'sız URL çıkarır. Netlify ve Vercel gibi platformların edge routing'i slash'sız yapıya yöneliktir. Statik site üreticilerinin büyük kısmı (Hugo, Eleventy) slash'sız URL üretir.

Mevcut sitede tutarsızlık varsa önce durum tespiti yapılır: curl -I example.com/sayfa ve curl -I example.com/sayfa/ çıktısını karşılaştırmak, her iki URL için dönen HTTP durum kodunu ve Location başlığını ortaya koyar. 200 + 200 kombinasyonu duplicate content durumunu doğrular; 200 + 301 ise yönlendirmenin zaten aktif olduğunu gösterir.

Nginx'te davranış farklıdır. Apache'nin DirectorySlash yönergesi Nginx'te karşılık bulmaz; bunun yerine try_files veya rewrite direktiflerinin açıkça yazılması gerekir. Mevcut Nginx yapılandırmasında trailing slash kuralı yoksa sunucu her iki URL'ye de 200 döndürebilir; bu durumda sorun görünmez kalır ama ortadan kalkmaz. Nginx için trailing slash kaldırma: rewrite ^/(.*)/$ /$1 permanent; satırı yeterlidir. Koşul yazımı Apache'ye göre daha sade olsa da, location bloğunun doğru kapsamda tanımlanması ve diğer rewrite kurallarıyla çakışmaması gerekir.

Karma strateji riski de göz ardı edilmemeli. Bazı dizinler için slash eklenip diğerleri için kaldırılırsa, kural yazımı hızla karmaşıklaşır ve bakım maliyeti artar. Bir URL için işleyen kural, başka bir URL yapısıyla çakışabilir; özellikle dinamik parametreler veya çoklu dil ön ekleri içeren URL'lerde beklenmedik yönlendirmeler üretilir. Site genelinde tek bir strateji seçip tüm URL yapısına uygulamak, hata ayıklama süresini önemli ölçüde kısaltır.

htaccess dosyasında trailing slash kuralı

.htaccess dosyasında trailing slash yönetimi, Apache'nin mod_rewrite modülüne dayanır. Modülün aktif olması ve AllowOverride All veya AllowOverride FileInfo yönergesinin httpd.conf'ta tanımlı olması gerekir.

Trailing slash kaldırma:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]

Buradaki !-d koşulu kritiktir. Bu koşul olmadan gerçek dizinler de slash'sız versiyona yönlendirilir; bu, Apache'nin dizin listesini veya index.html dosyasını bulmakta zorlanmasına neden olur. Koşul, gelen isteğin diskte gerçek bir dizine karşılık gelip gelmediğini kontrol eder; gerçek dizinse kural devreye girmez.

Trailing slash ekleme:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ /$1/ [R=301,L]

Burada iki koşul vardır: !-f ve !-d. Gerçek dosyalar ve dizinler kural dışında kalır; yalnızca sanal URL segmentleri (uygulama tarafından işlenen) yeniden yazılır.

Kural orada duruyor; ama Apache onu hiç okumadı.

En sık karşılaşılan durum budur: .htaccess dosyası doğru yazılmış, kurallar mantıklı görünüyor, ama yönlendirme çalışmıyor. Nedeni httpd.conf'taki AllowOverride None veya yanlış VirtualHost bloğunda tanımlanan AllowOverride'dır. Apache, AllowOverride None aktifken .htaccess dosyasını tamamen yok sayar; hiçbir hata döndürmez, sessizce geçer. Test için apache2ctl -t syntax kontrolü yapar; ama AllowOverride sorununu yakalamaz. Canlı ortamda curl -v ile yanıt başlıklarını doğrudan okumak daha güvenilirdir.

rewrite kurallarını otomatik olarak oluşturmak için bir araç kullanılabilir; önce tarayıcıda test edip ardından sunucuya atılır. El yazımında parantez, bayrak veya koşul sırası kolayca kaçar; üretilen çıktı bu hataları baştan önler.

Birden fazla .htaccess direktifi olan sitelerde kural sırası belirleyicidir. Başka bir RewriteRule daha önce eşleşip L bayrağıyla duruyorsa trailing slash kuralı hiç çalışmaz. Mevcut yönlendirme kurallarının sırası gözden geçirilmeli; trailing slash kuralı genellikle en üste veya tüm URL dönüşüm kurallarından önce konumlandırılır.

Yönlendirme zinciri oluştuğunda ne olur?

Trailing slash kuralı izole çalışmaz. Sunucuda daha önce http → https veya www → non-www 301 yönlendirmesi aktifse, trailing slash yönlendirmesi bu zincire eklenir.

Örnek akış: kullanıcı http://www.example.com/sayfa/ adresini ziyaret eder. Birinci kural: HTTP'den HTTPS'ye yönlendir (301). İkinci kural: www'dan non-www'ya yönlendir (301). Üçüncü kural: trailing slash'ı kaldır (301). Toplam üç yönlendirme, sayfaya ulaşmadan önce.

Her 301, bir tam HTTP döngüsü demektir. Tarayıcı her adımda yeni bir TCP bağlantısı açar veya mevcut bağlantıyı bekletir; bu, TTFB'ye doğrudan eklenir. Google, üç adımlık bir zinciri takip eder; ama zincir ne kadar uzarsa sinyal iletimi o kadar zayıflar. Dört veya daha fazla adımlık zincirlerde Googlebot zinciri takip etmeyi bırakabilir.

Çözüm, kural bloklarını doğru sırayla yazmaktır. HTTP→HTTPS ve www→non-www dönüşümü için tek bir blok yeterlidir; trailing slash kuralı hemen ardına eklenir.

RewriteEngine On
# HTTPS + www → tek 301
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]

# Trailing slash kaldır
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [R=301,L]

Aynı istekte her iki kural birden tetiklenmez. İlk kural eşleştiğinde [L] bayrağı değerlendirmeyi durdurur; tarayıcı HTTPS non-www URL'yi ister, bu sefer ikinci kural devreye girer. Sonuç: kullanıcı iki adımda hedefe ulaşır. Bu yapı, üç ayrı kural bloğunun ürettiği zincirleme 301 sorununu ortadan kaldırır.

Kural doğru çalışıyor mu?

Yapılandırma sonrası doğrulama, kural sözdiziminin kontrolünden farklıdır. apache2ctl -t veya nginx -t yalnızca parse hatası arar; yönlendirme mantığının beklenen davranışı üretip üretmediğini söylemez.

HTTP durum kodu testi için:

# Trailing slash olmadan
curl -I https://example.com/sayfa

# Trailing slash ile
curl -I https://example.com/sayfa/

Beklenen çıktı: slash'sız URL için 301 Moved Permanently ve Location: https://example.com/sayfa/; ya da tersi, seçilen stratejiye göre. İki URL için ikisi de 200 OK dönüyorsa yönlendirme aktif değildir.

Google Search Console Coverage raporu, hangi URL'lerin indekslendiğini gösterir. Hem slash'lı hem slash'sız versiyonlar "Indexed" veya "Crawled, not indexed" olarak görünüyorsa, yönlendirme henüz aktif değil ya da Googlebot eski kanonik kararını önbelleğinde tutuyor demektir. Yönlendirme aktif hale getirildikten sonra URL Denetleme aracıyla tekil URL testi yapılabilir; "Canonical" alanının hedef URL'yi gösterip göstermediği kontrol edilir.

Sunucu log dosyaları daha kesin bilgi verir: /var/log/apache2/access.log veya error.log üzerinden yönlendirme kuralının tetiklenip tetiklenmediği görülür. Log'da 301 kayıtları varsa kural çalışıyor; yoksa AllowOverride veya kural sırası sorununa bakılır. Log doğrulaması tamamlanmış olsa bile GSC Coverage raporu birkaç tarama turu boyunca eski canonical kararını yansıtmaya devam edebilir; bu beklenen bir gecikme, yapılandırma hatası değil.

Trailing slash tutarlılığı, iç link yapısından başlar. Sitemap'teki URL'lerin, iç linklerin ve canonical etiketlerin hepsi aynı formatı kullanıyorsa, Googlebot'un canonical tercihini oluşturması için gereken sinyal sayısı en aza iner. sitemap üretirken URL formatını tutarlı tutmak için bir araç kullanılırsa, manuel düzenlemelerden kaynaklanan slash tutarsızlıkları baştan önlenir.

Kuralın doğru çalıştığı doğrulandıktan sonra yapılacak son kontrol, sitenin iç linklerini taramaktır. iç link yapısındaki slash tutarsızlıklarını tespit etmek için link tarama yapılabilir; bu sayede .htaccess kuralı uygulanmış olsa bile yönlendirme zincirleri oluşturmadan doğru URL'ye işaret eden linkler yazılmış olur.