Googlebot JavaScript'i nasıl işliyor?
"Google JavaScript'i çalıştırıyor, o yüzden sorun yok" cümlesi yarı doğru. Google gerçekten JavaScript çalıştırıyor, ama bir kullanıcı gibi değil. Tıklamıyor, kaydırmıyor, izin pencerelerine cevap vermiyor ve bir sayfadan diğerine hiçbir şey taşımıyor. Sayfanızın içeriği bu davranışlardan birine bağlıysa, Google o içeriği görmüyor.
JavaScript ağırlıklı sitelerde karşılaştığım dizine ekleme sorunlarının çoğu, Googlebot'un sayfayı nasıl işlediği tam bilinmediği için ortaya çıkıyor. Süreci anladığınızda sorunların nereden geldiğini tahmin etmek kolaylaşıyor.
Üç aşama: tarama, render, dizine ekleme
Google'ın belgelerine göre JavaScript kullanan bir sayfa üç aşamadan geçiyor:
- Tarama (crawl): Googlebot URL'yi kuyruktan alıyor, önce robots.txt'ye bakıyor, izin varsa sayfayı indiriyor. Bu aşamada elde olan, sunucunun döndürdüğü ham HTML. Ham HTML içindeki
<a href>linkleri keşif için hemen kullanılabiliyor. - Render: Sayfa render kuyruğuna giriyor. Kaynaklar hazır olduğunda Google'ın Web Rendering Service'i sayfayı headless Chromium ile açıyor, JavaScript'i çalıştırıyor ve ortaya çıkan DOM'u alıyor.
- Dizine ekleme (index): Render edilmiş HTML'deki içerik ve linkler işleniyor, yeni bulunan linkler tarama kuyruğuna ekleniyor.
Render kuyruğunda bir sayfanın ne kadar bekleyeceği sabit değil. Google bu süre hakkında kesin bir rakam vermiyor ve ben de vermeyeceğim. Pratikteki sonuç şu: içerik ham HTML'de varsa, render beklemeden de değerlendirilebiliyor. İçerik sadece JavaScript ile geliyorsa, render tamamlanana kadar Google'ın elinde o içerik yok.
Bir nokta daha: Google'ın belgelerine göre 200 durum kodu dönen sayfalar render kuyruğuna alınıyor. Başlangıç HTML'inde noindex varsa Google render aşamasını atlayabiliyor.
Evergreen Chromium
Googlebot, Chromium'un güncel sürümünü kullanıyor (evergreen). Yani modern JavaScript özellikleri, ES modülleri, fetch ve benzeri API'ler destekleniyor. Eski tarayıcılar için polyfill yazmak SEO açısından gerekli değil.
Ama "tarayıcı güncel" demek "kullanıcı gibi davranıyor" demek değil. Sorunlar genelde tarayıcı motorundan değil, davranış farkından çıkıyor.
Googlebot'un yapmadığı şeyler
Tıklamıyor ve etkileşime girmiyor
Googlebot butonlara tıklamıyor, sekmeleri açmıyor, "Daha fazla yükle" butonuna basmıyor, form doldurmuyor. Sadece tıklamayla yüklenen içerik, Google için yok hükmünde. Sekmelerde duran içerik ilk HTML'de ya da render sonrası DOM'da mevcutsa ve sadece CSS ile gizleniyorsa sorun yok; tıklama sonrası fetch ile geliyorsa sorun var.
Kaydırmıyor
Google'ın belgelerine göre Googlebot sayfayı kaydırmıyor, bu yüzden scroll olayına bağlı içerik yüklemesi tetiklenmiyor. Bunun yerine Google, sayfayı uzun bir görüntü alanıyla render ediyor. Dolayısıyla IntersectionObserver ile yapılan lazy loading ve tarayıcının yerel loading="lazy" özelliği sorun çıkarmıyor; içerik görünür alana girdiği anda yüklendiği için render sırasında da yükleniyor. Sorun çıkaran, scroll olay dinleyicisine bağlı eski tip çözümler.
Sonsuz kaydırma (infinite scroll) kullanan listelerde de her sayfanın kendi URL'si olmalı ve bu URL'lere normal linklerle ulaşılabilmeli.
İzin istemlerini reddediyor
Konum, bildirim, kamera gibi izin istemleri Googlebot tarafından reddediliyor. İçeriği "kullanıcının konumunu al, sonra ürünleri göster" mantığıyla kurduysanız, izin reddedildiğinde de anlamlı bir içerik gösterdiğinizden emin olun.
Sayfalar arasında durum taşımıyor
Googlebot her sayfayı temiz bir oturumla açıyor. Google'ın belgelerine göre localStorage, sessionStorage ve çerezler sayfa yüklemeleri arasında temizleniyor. Bir önceki sayfada kaydedilen bir tercihe, bir A/B test atamasına ya da "daha önce ziyaret etti" bilgisine göre içerik gösteren kurgular Googlebot'ta farklı sonuç veriyor.
URL parçalarını (#) ayrı sayfa saymıyor
example.com/#/urunler gibi hash tabanlı yönlendirme kullanan uygulamalarda, # sonrası kısım Google için genelde ayrı bir sayfa anlamına gelmiyor. Router'ı History API ile (/urunler gibi gerçek yollar) çalışacak şekilde kurun. React Router, Vue Router ve benzerlerinde bu zaten varsayılan ya da tek satırlık bir ayar.
Linkler gerçek <a href> olmalı
Google, keşif için href özelliği olan <a> etiketlerini takip ediyor. onclick ile yönlenen div'ler, href içermeyen <a> etiketleri ya da javascript: ile başlayan linkler takip edilmiyor.
<!-- Takip edilir -->
<a href="/urunler/ayakkabi">Ayakkabı</a>
<!-- Takip edilmez -->
<span onclick="router.push('/urunler/ayakkabi')">Ayakkabı</span>
<a onclick="goTo('ayakkabi')">Ayakkabı</a>SPA framework'lerinin link bileşenleri (Next.js Link, Vue RouterLink) doğru kullanıldığında <a href> üretiyor. Özel bileşen yazdıysanız render edilmiş HTML'de gerçekten href olup olmadığını kontrol edin.
SPA'larda durum kodu ve soft 404
Tek sayfa uygulamalarında sunucu çoğu zaman her URL için aynı HTML kabuğunu 200 koduyla döndürüyor. Ürün bulunamadığında JavaScript "Bulunamadı" mesajı gösteriyor ama HTTP durum kodu hâlâ 200. Google bu sayfaları soft 404 olarak işaretleyebiliyor ya da daha kötüsü, binlerce boş sayfayı dizine eklemeye çalışabiliyor.
Google'ın önerdiği iki çözüm var: sunucunun gerçekten 404 döndürdüğü bir URL'ye JavaScript ile yönlendirmek ya da hata sayfasına JavaScript ile noindex eklemek. En temiz çözüm ise SSR ile doğru durum kodunu doğrudan sunucudan döndürmek. Bu seçenekleri React/Vue sitelerinde SSR ve SSG yazısında karşılaştırdım.
JavaScript ile eklenen meta robots
Meta robots etiketini JavaScript ile eklemek ya da değiştirmek mümkün, ama tek yönde güvenilir. Ham HTML'de noindex varsa Google render etmeden sayfayı dışarıda bırakabiliyor; JavaScript'in sonradan bu etiketi kaldırması işe yaramayabilir. Bu yüzden benim kuralım şu: dizine girmesini istediğiniz sayfada ham HTML'de asla noindex bulunmamalı. Aynı mantık canonical için de geçerli; ham HTML ile render sonrası DOM'da farklı canonical değerleri olması, Google'a çelişkili sinyal göndermek demek.
robots.txt ile kaynak engelleme
Render için Googlebot'un JavaScript dosyalarına, CSS'e ve içeriğin geldiği API uç noktalarına erişebilmesi gerekiyor. robots.txt'de /api/ ya da /static/js/ gibi dizinleri engellediyseniz, sayfa render sırasında içeriksiz kalıyor. Engelleri robots.txt test aracı ile kontrol edebilirsiniz.
Google'ın belgelerine göre Web Rendering Service önbellek başlıklarını her zaman dikkate almayabiliyor. Bu yüzden JavaScript ve CSS dosyalarında içerik parmak izi (ör. app.3f9a1c.js) kullanmak, Google'ın eski bir dosyayla render etmesini önlüyor.
Zaman aşımları
Render sırasında ne kadar beklendiğine dair kesin bir sayı paylaşılmıyor ve internette dolaşan rakamların çoğu deneylere ya da eski açıklamalara dayanıyor. Pratik sonuç yine aynı: ana içeriği ve linkleri geciktirmeyin. İçerik zincirleme API çağrılarının sonunda geliyorsa, render tamamlandığında hazır olmama ihtimali artıyor.
Test: Google ne görüyor?
Search Console'daki URL Denetimi (URL Inspection) aracı en güvenilir kaynak. Dizine eklenmiş sürüm için "Taranan sayfayı görüntüle" (View crawled page), güncel sürüm için "Canlı URL'yi test et" (Test live URL) seçeneğini kullanın. Açılan panelde HTML sekmesi render edilmiş HTML'i gösteriyor; ekran görüntüsü ve "Diğer bilgiler" bölümündeki yüklenemeyen kaynaklar da burada.
Kontrol ettiğim şeyler: ana içerik render edilmiş HTML'de var mı, linkler href içeriyor mu, title ve canonical beklenen değerde mi, yüklenemeyen kritik bir kaynak var mı. Ham HTML ile render edilmiş hâli sistemli karşılaştırmak için render farkını test etmek yazısındaki betiği kullanabilirsiniz.
Özetle
- Ana içerik ve linkler tıklama, kaydırma ya da izin gerektirmeden DOM'a geliyor.
- Bütün linkler
<a href>; router#yerine gerçek yollar kullanıyor. - Olmayan sayfalar 404 dönüyor ya da
noindexalıyor. - Dizine girecek sayfaların ham HTML'inde
noindexyok. - JS, CSS ve API uç noktaları robots.txt ile engellenmemiş.
- İçerik localStorage, çerez ya da önceki sayfa durumuna bağlı değil.
- URL Denetimi'ndeki render edilmiş HTML beklediğiniz içeriği gösteriyor.
Comments / questions
If you have a question about any topic or wish to contact me: Telegram or send an email to [email protected] Thanks!
Related pages
- React ve Vue sitelerinde SEO: SSR, SSG ve prerender (2026)
- Search Console'daki her dizine ekleme durumunun Türkçe anlamı (2026)
- Sunucu logları ile SEO: cPanel loglarında Googlebot analizi (2026)
- Crawl budget gerçekten sorun mu? Hangi sitede önemli, nasıl ölçülür (2026)
- Google'ın hiç ziyaret etmediği sayfaları loglarla bulmak (2026)