Hreflang ve CDN: Edge Üzerinden Sunulunca Yaşanan Sorunlar

CDN edge katmanında hreflang sinyalinin önbellek nedeniyle bozulmasını temsil eden editoryal blog görseli

Kaynak kodda hreflang etiketleri eksiksiz, sitemap doğru, karşılıklı referanslar tutarlı; test araçları "temiz" diyor. Ama Google Search Console haftalar sonra yanlış dil sürümünü göstermeye devam ediyor ya da bazı bölgelerden gelen kullanıcılar aniden başka bir dildeki sayfayı görüyor. Sorunun kaynağı origin sunucu değil; origin ile Googlebot arasına giren CDN katmanı, dinamik olarak üretilen hreflang sinyalini kendi önbellek mantığıyla sessizce bozuyor.

CDN, bir web sayfası için tek bir gerçeklik olmadığını hatırlatan katmandır. Aynı URL, coğrafi konuma, önbellek durumuna ve edge node'a bağlı olarak farklı zamanlarda farklı içerik döndürebilir. Çok dilli bir sitede bu davranış, dil ve bölge kararının doğrudan URL yapısına değil de sunucu mantığına bağlı olduğu her kurulumda risk üretir. Header tabanlı hreflang, dinamik locale tespiti ve edge fonksiyonlarıyla yapılan yönlendirmeler, CDN'in cache katmanıyla çarpıştığında hangi sürümün kime ulaştığı artık origin'in kontrolünde değildir.

CDN katmanı hreflang zincirine neden bir aracı ekliyor?

Hreflang üç yoldan biriyle taşınır: HTML head içinde link etiketi, XML sitemap içinde alternate kaydı veya HTTP response header'ı. İlk ikisi statik dosya içeriğinin bir parçası olduğu için CDN'in önbellek mantığından nispeten bağımsız çalışır; CDN bu içeriği olduğu gibi kopyalar ve dağıtır. Üçüncü yöntem farklıdır. HTTP header, response'un kendisiyle birlikte üretilir ve CDN'in önbellek katmanı bu header'ı korumak, iletmek veya yeniden üretmek konusunda origin sunucudan bağımsız kararlar verebilir.

Bir CDN, önbelleğe alınmış bir response'u sunarken varsayılan olarak yalnızca belirli header setini geçirir; özel header'lar (Link header üzerinden taşınan hreflang dahil) bu setin dışında kalıyorsa, edge node origin'e hiç gitmeden aynı içeriği tekrar tekrar sunduğunda header sessizce düşer. Sonuç, tarayıcıda sayfa normal görünür, ama Googlebot'un hangi sayfayı sunduğunu ölçtüğünüzde hreflang setinin bazı önbellek isabetlerinde tamamen kayıp olduğunu görürsünüz.

Cache key'de dil sinyali yoksa hangi sürüm herkese sunulur?

Her CDN, bir response'u önbelleğe koyarken bir "cache key" üretir; bu anahtar genellikle URL yolunu, sorgu parametrelerini ve bazen belirli header'ları kapsar. Dil kararı Accept-Language başlığına, bir cookie'ye veya IP'ye göre origin'de dinamik olarak veriliyorsa ve bu sinyal cache key'in bir parçası değilse, CDN aynı URL için tek bir response'u önbelleğe alır ve bu response'u gelen her isteğe, hangi dilde talep edilmiş olursa olsun sunar.

Pratikte bu şu senaryoyu üretir: Türkiye'den gelen ilk ziyaretçi Türkçe sürümü tetikler, CDN bu response'u önbelleğe alır; hemen ardından Almanya'dan gelen bir ziyaretçi aynı URL'ye gittiğinde, edge node origin'e hiç sormadan önbellekteki Türkçe içeriği döndürür. Aynı URL farklı hreflang kümeleriyle farklı kullanıcılara sunulmuş gibi görünür, ama gerçekte tek bir önbellek girdisi tüm trafiği karşılıyordur. Bu, klasik anlamda bir hreflang hatası değildir; hreflang etiketleri doğru üretilmiş olabilir, sorun bu üretimin hangi kullanıcıya ulaştığıdır.

HTTP header yöntemiyle hreflang CDN'de neden silinebiliyor?

HTML, sitemap ve HTTP header yöntemleri arasındaki karşılaştırma genellikle PDF gibi HTML dışı içerikler için header yöntemini önerir; ama bazı kurulumlarda HTML sayfaları için de Link header üzerinden hreflang taşınır. Bu tercih, CDN devredeyken ek bir kırılganlık noktası açar. Çoğu CDN yapılandırması varsayılan olarak Content-Type, Cache-Control, ETag gibi standart header'ları korur; Link header özel amaçlı kullanıldığında bu koruma listesine dahil edilmemiş olabilir.

Bu durum edge fonksiyonu veya reverse proxy katmanında da tekrarlanır. Bir edge worker, response'u origin'den aldıktan sonra kendi mantığıyla yeniden yazıyorsa (örneğin sıkıştırma, HTML minifikasyonu veya güvenlik header'ı ekleme amacıyla) ve bu yeniden yazma işlemi header kopyalama adımını atlıyorsa, hreflang header'ı fark edilmeden düşer. Sorunun kaynağı origin sunucuda test edildiğinde tamamen sağlıklı görünür; hata yalnızca CDN üzerinden geçen gerçek trafikte ortaya çıkar. Bu yüzden hreflang doğrulaması origin'e değil, canlı domaindeki gerçek response'a karşı yapılmalıdır.

Edge'de stale cache: içerik güncellenir, hreflang set eskisinde kalır

Yeni bir dil sürümü eklendiğinde veya mevcut bir sayfanın hreflang kümesi genişletildiğinde, origin sunucu güncel HTML'i anında üretir. CDN'in önbellek katmanı bu değişikliği ise kendi TTL (time to live) süresine göre yansıtır. TTL uzun ayarlanmışsa, güncellenmiş hreflang kümesi origin'de doğru olsa bile, edge node'lar eski sürümü saatlerce veya günlerce sunmaya devam eder.

Yeni dil eklerken hreflang kümesinin geriye dönük genişletilmesi gerektiğinden bahsedilir, ama bu genişletme çoğu ekip listesinde CDN purge adımı yer almaz. Sonuç, GSC'de günlerce "eksik hreflang" veya "no return tag" hatası görülür; oysa origin dosyaları düzeltmenin yapıldığı gün doğru hale gelmiştir. Sorun kodda değil, dağıtım katmanının gecikmesindedir. TTL süresi bir saatten uzun tutulan sitelerde, hreflang değişikliği içeren her yayın sonrası ilgili URL'ler için manuel purge işlemi rutine dahil edilmelidir.

Vary başlığı eksikse tarayıcı ile bot aynı önbellek girdisini paylaşır

Vary HTTP header'ı, CDN'e "bu response, belirtilen isteğe bağlı header'a göre farklılaşabilir, ayrı ayrı önbelleğe al" talimatı verir. Accept-Language başlığına göre dil kararı veren bir kurulumda Vary: Accept-Language eksikse, CDN tek bir dil sürümünü tüm Accept-Language değerleri için ortak önbellek girdisi olarak kullanır. Bu, önceki bölümdeki cache key sorununun header seviyesindeki karşılığıdır ve genellikle aynı kök nedenden kaynaklanır.

Vary header eklemenin kendi riski de vardır. Vary: Accept-Language tanımlandığında, tarayıcıların gönderdiği Accept-Language değerlerinin pratikte neredeyse hiç aynı olmaması (dil önceliği sıralaması, bölge kodu varyasyonları) CDN'in aynı içerik için düzinelerce ayrı önbellek girdisi oluşturmasına yol açabilir. Bu durumda önbellek isabet oranı çöker, her istek origin'e gider ve CDN'in performans avantajı fiilen ortadan kalkar. Doğru çözüm genellikle Vary header'ını değil, dil kararını URL yapısına (alt dizin veya alt domain) taşımaktır; bu, cache key sorununu Accept-Language header'ına bağımlı kalmadan kökten çözer ve Accept-Language tabanlı yönlendirmenin taşıdığı diğer risklerle de örtüşür.

CDN sağlayıcıları arasında header ve cache davranışı nasıl farklılaşır?

Bu davranışlar CDN sağlayıcısına göre değişir ve genelleme yaparken dikkatli olunmalıdır. Bazı platformlarda özel response header'ları varsayılan olarak korunur ve geçirilir; bazılarında ise önbellekten sunulan response'larda özel header'ların açıkça bir kural veya yapılandırma listesine eklenmesi gerekir. Edge fonksiyon (worker, edge compute) katmanı kullanılan kurulumlarda header davranışı yazılan koda bağlıdır; fonksiyon origin'den gelen response'u değiştirip yeniden döndürürken header kopyalama işlemini atlarsa, platform bağımsız olarak aynı sorun tekrarlanır.

Pratik sonuç şudur: bir CDN yapılandırmasını "hreflang'ı koruyor" diye kabul etmek, o platformun genel dokümantasyonuna değil, o siteye özel gerçek response testine dayanmalıdır. Aynı CDN sağlayıcısı, bir müşteride varsayılan ayarlarla hreflang header'ını sorunsuz geçirirken, özel bir cache kuralı veya edge fonksiyonu eklenmiş başka bir kurulumda aynı header'ı düşürebilir. Yapılandırma değiştiği anda önceki test sonucu geçerliliğini kaybeder.

Purge stratejisi: hreflang değiştiğinde önbellek nasıl temizlenir?

Hreflang kümesini etkileyen her değişiklik (yeni dil ekleme, bir sayfanın canonical'ının değişmesi, bir dil sürümünün kaldırılması) CDN önbelleğinde karşılığını bulmalıdır. Kapsamlı ama kaba bir yöntem, tüm domain için önbelleği temizlemektir; bu işe yarar ama trafiği anlık olarak origin'e yönlendirdiği için sunucu yükünü artırır ve büyük sitelerde tercih edilmez.

Daha kontrollü yaklaşım, değişen URL'lerin ve bu URL'lerin hreflang setinde birlikte anıldığı diğer dil sürümlerinin hedefli olarak purge edilmesidir. Bir sayfanın Türkçe sürümü güncellendiğinde, sadece o URL değil, karşılıklı referans verdiği İngilizce ve Almanca sürümler de purge listesine eklenmelidir; aksi halde bu sürümler eski hreflang setini önbellekte tutmaya devam eder ve karşılıklı referans zinciri fiilen kopar. Otomatik yayın süreçlerinde bu purge adımının deploy script'ine dahil edilmesi, manuel takibe bırakılmasından daha güvenilirdir; manuel süreçlerde bu adım büyük ihtimalle bir noktada atlanır.

Cache TTL süresini kısaltmak alternatif bir çözüm gibi görünür, ama bu CDN'in temel faydasını (origin yükünü azaltmak, gecikmeyi düşürmek) zayıflatır. Daha sürdürülebilir denge, statik ve nadiren değişen sayfalarda uzun TTL kullanıp hedefli purge ile güncellemeyi anlık yapmak; sık güncellenen sayfalarda ise zaten kısa TTL tercih etmektir. Hreflang kümesi sabit kalan bir site için bu ayrım büyük önem taşımaz; sık dil ekleyen veya düzenli teknik denetim yapılan büyük ölçekli projelerde ise purge stratejisi hreflang bakımının ayrılmaz bir parçası olmalıdır.

CDN'i devre dışı bırakmak çoğu site için gerçekçi bir çözüm değildir; performans ve maliyet avantajları hreflang riskinden çok daha büyüktür. Doğru yaklaşım, CDN yapılandırmasını hreflang'ın taşınma yöntemine göre şekillendirmektir. HTML head içinde statik olarak üretilen hreflang etiketleri, CDN'in doğasıyla en uyumlu yöntemdir çünkü sayfa içeriğinin bir parçası olarak taşınır ve özel header koruma kuralına ihtiyaç duymaz. Header tabanlı veya dinamik locale tespitine dayanan kurulumlarda ise cache key, Vary header ve purge süreci, hreflang doğruluğunun HTML kadar kritik bir bileşeni olarak ele alınmalıdır. Bu üç ayarın hiçbiri kod incelemesinde görünmez; ancak canlı domaindeki gerçek response başlıkları test edildiğinde ortaya çıkar.