TechnoRadical İletişime geçin

TechnoRadical notları · Makale

JavaScript ile render edilen içerik indekslenir mi?

JavaScript ile render edilen içerik Google'da üç aşamada, belirsiz bir gecikmeyle indekslenir. Kendi aracımızın bu sorunu nasıl yaşadığını gösteriyoruz.

JavaScript ile render edilen içerik, Google’ın crawling, rendering ve indexing olarak ayırdığı üç aşamalı bir süreçle indekslenir; rendering ayrı bir kuyrukta ve kasıtlı olarak belirsiz bırakılmış bir gecikmeyle çalışır. Bu gecikmenin resmi bir üst sınırı yok, Google yalnızca alt sınırın birkaç saniye olduğunu, sürenin daha da uzayabileceğini yazıyor. Dynamic rendering, Google tarafından resmi olarak “geçici çözüm, uzun vadeli çözüm değil” diye tanımlanıyor; tercih edilen sıra sunucu tarafı render, statik render ve hydration. TechnoRadical’ın kendi /denetim/ aracı bu sorunu birebir yaşıyor: crawler.py modülü JavaScript çalıştırmadan yalnızca ham HTTP yanıtını okuyor, bu yüzden istemci tarafında render edilen bir sayfada aracın “temiz” sonucu render başarısının kanıtı sayılmıyor. Bir sayfanın gerçekten render edilip indekslendiği, Search Console URL İnceleme aracındaki “İncelenen sayfayı görüntüle” ekranıyla, render edilmiş ekran görüntüsü, ham HTML ve JavaScript konsol çıktısı karşılaştırılarak doğrulanabiliyor. Next.js App Router kullanan projelerde bu sorun genelde daha az görülüyor, çünkü sayfa ve layout’lar varsayılan olarak sunucu tarafında render ediliyor.

Google, JavaScript ile oluşturulan içeriği indeksler mi

Google, JavaScript ile oluşturulan içeriği indeksler, ama bunu crawling, rendering ve indexing olmak üzere üç ayrı aşamada yapar; rendering aşaması ayrı bir kuyrukta ve gecikmeli çalışır.

Google Search Central’ın JavaScript SEO temelleri sayfası bu üç aşamayı ayrı ayrı tanımlıyor. Googlebot önce sayfayı tarar (crawling), sonra JavaScript’i çalıştırıp sayfayı oluşturur (rendering), son olarak ortaya çıkan içeriği dizine ekler (indexing). Sayfa, rendering’in ayrı bir kuyrukta beklediğini şöyle belirtiyor: “Googlebot, sayfaları hem tarama hem render kuyruğuna alır.” Render için kullanılan motor, Chrome’un güncel sürümüyle senkronize çalışan ve sabit bir sürüm numarası taşımayan bir Chromium sürümü; Google buna “evergreen Chromium” diyor. Bu üç aşama, keşif ve sunumla birlikte bir sayfanın Google’da görünmesini belirleyen beş aşamalı pipeline’ın ortasını oluşturur; bu beş aşamanın hangisinde bir sayfanın takıldığının gerçek bir sunucu log satırı ve Search Console ekranıyla nasıl teşhis edileceği ayrı bir yazının konusudur.

Bu iki aşamalı yapı yalnızca istemci tarafında (CSR, client-side rendering) render edilen sitelerde fark yaratıyor. Sunucu tarafında render edilen (SSR, server-side rendering) veya derleme anında statik HTML üreten (SSG, static site generation) bir sitede ana içerik ilk HTTP yanıtında zaten tam olarak hazır; Googlebot’un ayrıca JavaScript çalıştırıp render kuyruğunda beklemesine gerek kalmıyor.

Rendering neden gecikmeli: kuyruk ve kasıtlı olarak belirsiz süre

Google, rendering kuyruğunda geçen sürenin kesin bir üst sınırı olmadığını kendi dokümantasyonunda açıkça yazıyor; alt sınır birkaç saniye, üst sınır tanımlı değil.

Google Search Central’ın ilgili sayfası şu cümleyi taşıyor: “Sayfa bu kuyrukta birkaç saniye kalabilir, ama bundan daha uzun sürebilir.” Bu ifade tesadüfen belirsiz bırakılmamış; Google bilerek bir üst sınır vermiyor, çünkü gecikme siteye, sunucu hızına ve o anki render kuyruğu yüküne göre değişiyor. Rendering gecikmesi yalnızca JavaScript’e özgü, ayrı bir aşama; teknik SEO denetiminin kapsadığı diğer katmanlardan (tarama, indeksleme, sayfa deneyimi) yalnızca biri, geri kalanı ayrı bir yazıda ele alınıyor.

TR SEO içeriğinde bu belirsizlik genelde korunmuyor. Sektörde dolaşan bir iddia, render süresini kaynaksız biçimde “ortalama birkaç saniye ile birkaç dakika arasında” diye sabit bir aralığa oturtuyor; bu rakamın kaynağı yok ve Google’ın kendi açık uçlu ifadesiyle çelişiyor. Bunun pratik sonucu şu: bir sayfanın neden hâlâ indekslenmediği sorusuna sabit bir gün veya saat sayısıyla cevap verilemez. Elde olan tek şey, Search Console’un kendi doğrulama yöntemidir, sabit bir bekleme süresi değil.

Kendi denetim aracımız bu sorunu neden birebir yaşıyor

TechnoRadical’ın kendi /denetim/ aracı JavaScript çalıştırmıyor; crawler.py modülü yalnızca ham bir HTTP GET isteği atıp dönen HTML’i okuyor, headless tarayıcı veya başka bir JavaScript motoru kullanmıyor.

Bu, kod tabanının doğrudan okunmasıyla doğrulandı. 05-araclar/denetim/crawler.py modülü httpx kütüphanesiyle sayfaya istek atıyor ve gelen ham HTML’i ayrıştırıyor. Sonuç olarak araç, Googlebot’un birinci dalgasıyla (crawling) aynı HTML’i görüyor; ikinci dalgada (rendering) JavaScript çalıştıktan sonra ortaya çıkan içeriği hiç göremiyor.

Bu sınırın önemi, sitenin render yöntemine göre değişiyor. TechnoRadical’ın kendi sitesi Astro ile statik üretildiği (SSG) için ham HTML zaten tam içeriği taşıyor, araç burada hiçbir şey kaçırmıyor. İstemci tarafında (CSR) render edilen bir sayfada durum farklı: aracın “temiz” sonucu, sayfanın gerçekten render edildiğinin veya indekslendiğinin kanıtı sayılamaz; araç yalnızca ham HTML katmanını görebiliyor, render sonrası katmanı görmüyor.

JavaScript SEO’da sık görülen üç hata

JavaScript ile çalışan sitelerde en sık tekrar eden üç hata, JavaScript ile enjekte edilen canonical etiketinin çelişkili hale gelmesi, fragment tabanlı yönlendirmenin Google tarafından tanınmaması ve dynamic rendering’in kalıcı bir çözüm sanılmasıdır.

Birinci hata canonical etiketiyle ilgili. Google’ın JavaScript SEO temelleri sayfası, canonical etiketinin JavaScript ile eklenmesinin mümkün olduğunu ama önerilmediğini yazıyor; eklenecekse sayfada yalnızca tek bir rel=canonical etiketi bulunmasına dikkat edilmeli, çünkü yanlış uygulama birden fazla veya çelişkili canonical üretebiliyor. Aynı doküman ailesindeki yinelenen URL rehberi en iyi yöntemi şöyle tanımlıyor: canonical URL’yi kaynak HTML kodunda statik olarak belirtmek, JavaScript’i yalnızca kaynak koda eklenemediği durumlarda kullanmak. Pratikte bu hata, bir şablonun hem statik bir canonical hem de çalışma zamanında farklı bir canonical enjekte etmesiyle ortaya çıkıyor; tarayıcıda sayfayı incelerken yalnızca son, render edilmiş hâl görünüyor, kaynak koddaki çelişkili ilk etiket gözden kaçıyor. Bu hata, kanonik etiketin on bir farklı sessiz bozulma kalıbından yalnızca biri; CMS eklentisi hataları, hreflang uyuşmazlığı ve sunucu yanlış yapılandırması gibi geri kalan kalıplar ayrı bir yazıda işleniyor.

İkinci hata, istemci tarafı yönlendirmede yalnızca URL fragment’inin (# işaretinden sonraki kısım) değişmesi. Google’ın JavaScript sorun giderme rehberi bunu doğrudan yasaklıyor: “URL fragment’lerini farklı içerik yüklemek için kullanmayın.” Bu uyarı, 2015’te kullanımdan kaldırılan eski AJAX crawling şemasının yerini alan History API’ye (tarayıcının adres çubuğunu JavaScript ile güncelleyen resmi arayüz) işaret ediyor. #/urun/123 gibi bir rotada sunucu her zaman aynı tek HTML’i döndürüyorsa ve ürüne özel içerik yalnızca JavaScript çalıştıktan sonra beliriyorsa, Google bu deseni 2015’ten beri tanımıyor.

Üçüncü hata, dynamic rendering’in tek sayfa uygulamaları (SPA) için kalıcı, standart bir çözüm sanılması. Google’ın dynamic rendering sayfası bunu açıkça sınırlıyor: “Dynamic rendering, JavaScript kaynaklı içerik sorunları için bir geçici çözümdü, uzun vadeli bir çözüm değil.” Google’ın tercih sırası sunucu tarafı render, statik render ve hydration; dynamic rendering yalnızca hızlı değişen, JavaScript kaynaklı içerik veya crawler’ların desteklemediği JS özellikleri gibi dar senaryolarda hâlâ savunulabilir bir seçenek.

CSR, SSR, SSG ve dynamic rendering arasında hangisi ne zaman seçilir

Yeni bir proje kuruluyorsa SSR veya SSG baştan seçilmeli; dynamic rendering yalnızca mevcut bir CSR uygulamasında geçiş dönemi çözümü olarak düşünülmeli.

Dört yöntem arasındaki fark, nasıl çalıştıkları ve indeksleme riskleri özeti şöyledir.

YöntemNasıl çalışırİndeksleme riskiNe zaman tercih edilir
CSR (client-side rendering)Tarayıcı boş bir HTML iskeleti alır, içerik JavaScript çalıştıktan sonra oluşurEn yüksek: içerik yalnızca rendering aşamasından sonra görünürDizine girmesi kritik olmayan panel veya uygulama ekranlarında
SSR (server-side rendering)Sunucu her istekte HTML’i o anki veriyle oluşturup gönderirDüşük: ana içerik ilk yanıtta hazırSık güncellenen veya kişiselleştirilmiş sayfalarda
SSG (static site generation)HTML, derleme (build) anında önceden üretilirEn düşük: ham HTML zaten tam içerik taşırİçeriği nadiren değişen blog, dokümantasyon ve pazarlama sayfalarında
Dynamic renderingBot’a ayrı, sunucu tarafında render edilmiş bir HTML gösterilir, kullanıcıya normal CSR sunulurOrta, Google’ın kendisinin “geçici çözüm” dediği son çareHızlı değişen JS içeriği veya crawler’ın desteklemediği JS özelliği gibi dar, geçiş dönemi senaryolarında

Next.js kullanan projelerde bu tabloyu okumadan önce bilinmesi gereken bir varsayılan var: App Router’da sayfa ve layout’lar varsayılan olarak Sunucu Bileşeni’dir (Server Component). Next.js’in resmi dokümantasyonu şöyle yazıyor: “Varsayılan olarak layout’lar ve sayfalar Sunucu Bileşenleridir.” İstemci bileşeni yalnızca durum (state), olay yöneticisi (event handler) veya tarayıcıya özel bir API gerektiğinde, dosyanın en üstüne "use client" direktifi eklenerek devreye giriyor. Bu, çoğu Next.js App Router sayfasının zaten sunucu tarafında render edildiği, JavaScript SEO sorununun yalnızca geliştiricinin bilinçli olarak "use client" ile işaretlediği bileşenlerde ortaya çıktığı anlamına geliyor.

Karar kuralı basit: yeni bir proje SSR veya SSG ile kuruluyorsa dynamic rendering’e hiç ihtiyaç yok. Mevcut bir CSR uygulaması varsa ve tam SSR’a geçiş kısa vadede mümkün değilse, dynamic rendering yalnızca geçiş döneminde, dar kapsamlı bir çözüm olarak kullanılmalı; Google’ın kendi ifadesiyle bu bir son çare, kalıcı bir mimari değil.

Bir sayfanın gerçekten render edilip indekslendiği nasıl doğrulanır

Bir sayfanın gerçekten render edilip edilmediğini doğrulamanın resmi yolu, kaynak kodu tahmin etmek değil, Search Console’un URL İnceleme aracıyla Google’ın o sayfayı canlı olarak nasıl gördüğünü görmektir.

Doğrulama beş adımdan oluşuyor.

  1. Search Console’da URL İnceleme aracını açın, ilgili URL’yi yapıştırın.
  2. “Canlı URL’yi test et” seçeneğini çalıştırın, test tamamlanınca “İncelenen sayfayı görüntüle”ye tıklayın.
  3. Açılan ekranda render edilmiş sayfanın ekran görüntüsünü, dönen ham HTML’i, HTTP başlıklarını ve JavaScript konsol çıktısını karşılaştırın; ana içerik ekran görüntüsünde görünüp ham HTML’de yoksa, içerik yalnızca render sonrası oluşuyor demektir.
  4. JavaScript konsolunda hata varsa (beklenmeyen script engeli, süresi dolan istek gibi) rendering’in tamamlanmamış olabileceğini not edin; bu hataların giderilmesi öncelikli olmalı.
  5. Tarayıcıda sayfa kaynağını görüntülemek (view-source) ile Öğeyi denetle/DOM görünümünü karşılaştırmak, aynı ayrımı ücretsiz ve anında, yerel olarak da gösterir.

Search Console Yardım’ın URL İnceleme sayfası bu ekranın içeriğini açıkça tanımlıyor: render edilmiş sayfanın ekran görüntüsü, dönen ham HTML, HTTP başlıkları, JavaScript konsol çıktısı ve yüklenen sayfa kaynakları görüntülenebiliyor. Ekran görüntüsü yalnızca başarılı bir canlı test sonucunda kullanılabiliyor.

Render edilmiş HTML’de yapılandırılmış veri de varsa, bu adımdan sonraki doğal kontrol JSON-LD’nin geçerliliği oluyor; şema aracıyla render edilmiş sayfadaki yapılandırılmış verinin türü ve zorunlu alanları eksiksiz mi diye ayrıca doğrulanabilir.

JavaScript SEO kontrol listesi: yayın öncesi ve sonrası

Google’ın JavaScript siteleri için verdiği dokuz maddelik öneri listesi, geliştiricinin yayın öncesi kontrol listesine dönüştüğünde altı kalemde toplanıyor; yayın sonrası kontrol ise render/indeks doğrulamasının tek seferlik değil, tekrarlanan bir adım olmasını gerektiriyor.

Yayın öncesi kontrol listesi altı maddeden oluşuyor.

  • Her sayfada benzersiz title ve meta açıklama kullanılır.
  • Sayfada tek ve statik bir rel=canonical etiketi bulunur; JavaScript ile enjekte edilen ikinci bir etiket çelişki yaratır.
  • Fragment değil History API tabanlı routing kullanılır.
  • Anlamlı HTTP durum kodları döner; bulunamayan sayfa gerçek bir 404 veya 410 kodu taşır, soft 404 kullanılmaz.
  • Robots meta etiketleri dikkatli kullanılır, yanlışlıkla noindex bırakılmaz.
  • Yapılandırılmış veri eklenir ve render edilmiş HTML’de görünür kalır; lazy-loaded içerik kullanıcı scroll etmeden veya etkileşime girmeden erişilebilir kalır.

Yayın sonrası kontrol, Search Console URL İnceleme aracıyla yapılan beş adımlık doğrulamanın tekrarıdır; bu adım yayının hemen ardından bir kereye mahsus değil, her önemli içerik güncellemesinden sonra tekrarlanır.

Bu maddelerin çoğu (title, canonical, HTTP durum kodu, robots meta) ham HTML katmanında da görülebilir; site denetimi aracının ham HTML katmanını taraması bu maddeleri tek seferde otomatik kontrol ediyor, ama araç JavaScript çalıştırmıyor, yalnızca ham HTTP yanıtını okuyor. Aracın temiz sonucu rendering’in başarılı olduğunun kanıtı değildir, yalnızca ham HTML düzeyinde bir hata olmadığının kanıtıdır; render katmanının doğrulaması Search Console URL İnceleme aracıyla yapılır.

JavaScript SEO · rendering · teknik SEO · Next.js

Bu yazıdakileri kendi sitenizde ölçmek ister misiniz?

Araçların hepsi ücretsiz ve kayıt istemiyor. Yazıda geçen ölçütlerin çoğunu doğrudan kendi adresinize uygulayabilirsiniz.

Ücretsiz denetim Diğer yazılar