React, Vue, Angular veya Next.js ile kurulmuş bir sitede en sık duyulan soru şu: “Google JavaScript'i okuyabiliyor mu?” Kısa cevap evet. Google Arama JavaScript'i, sürekli güncellenen (evergreen) bir Chromium sürümüyle çalıştırıyor. Uzun cevap ise şu: Google'ın bazı sınırlamaları var ve JavaScript sitelerinde içerik, link veya durum kodu hataları, klasik HTML sitelerinde olmayan şekillerde ortaya çıkabiliyor.

Bu rehberde Google'ın JavaScript sayfalarını nasıl taradığını, render ettiğini ve dizine eklediğini, sunucu taraflı ve istemci taraflı render arasındaki farkı, dinamik render'ın neden artık önerilmediğini, linkler, lazy loading ve tek sayfalık uygulamalardaki (SPA) soft 404 sorununu, son olarak da URL Denetimi aracıyla nasıl test edeceğinizi anlatıyoruz. JavaScript'in temellerine yabancıysanız önce JavaScript nedir yazımıza göz atabilirsiniz.

Google JavaScript’i üç aşamada işler: tarama, render, dizine ekleme

Google JavaScript’i üç aşamada işler: tarama, render, dizine ekleme: Tarama, İlk işleme, Render, Dizine ekleme

Google'ın belgesine göre Googlebot sayfaları hem tarama hem de render için kuyruğa alır ve bir sayfanın hangi kuyrukta beklediği dışarıdan hemen anlaşılmaz. Süreç kabaca şöyle işler:

  • Tarama: Googlebot URL'yi kuyruktan alır ve önce robots.txt'ye bakar. URL engellenmişse istek yapılmaz. Google, engellenmiş dosyalardan veya engellenmiş sayfalarda JavaScript render etmez.
  • İlk işleme: HTTP yanıtındaki HTML'de href niteliği olan linkler bulunur ve tarama kuyruğuna eklenir.
  • Render: HTTP durum kodu 200 olan tüm sayfalar, robots meta etiketi veya başlığı dizine eklemeyi engellemiyorsa, JavaScript olsun olmasın render kuyruğuna gönderilir. Sayfa bu kuyrukta birkaç saniye kalabilir, ama daha uzun da sürebilir. Kaynaklar elverdiğinde başsız (headless) bir Chromium sayfayı render eder ve JavaScript'i çalıştırır.
  • Dizine ekleme: Google render edilmiş HTML'deki linkleri yeniden ayrıştırır ve sayfayı dizine eklemek için render edilmiş HTML'yi kullanır.

İki ayrıntı önemli: 200 dışındaki durum kodlarında (örneğin 404 hata sayfalarında) render atlanabilir. Ayrıca Google bir sayfada noindex gördüğünde render'ı ve JavaScript çalıştırmayı atlayabilir.

Sunucu taraflı mı, istemci taraflı render mı?

“App shell” modelinde ilk HTML gerçek içeriği içermez; Google içeriği görmek için JavaScript'i çalıştırmak zorundadır. Google, sunucu taraflı render'ın (SSR) veya ön render'ın hâlâ çok iyi bir fikir olduğunu, çünkü siteyi hem kullanıcılar hem tarayıcılar için hızlandırdığını ve her botun JavaScript çalıştıramadığını belirtiyor.

Yaklaşımİlk HTML’de içerikGoogle’ın tutumu
Sunucu taraflı render (SSR)VarÖnerilen çözümlerden biri
Statik render / ön renderVarÖnerilen çözümlerden biri
Hydration (SSR + istemcide etkileşim)VarÖnerilen çözümlerden biri
İstemci taraflı render (CSR)Yok, JavaScript ile eklenirGoogle görebilir ama sınırlamalar var; diğer arama motorları JavaScript’i yok sayabilir
Dinamik renderBotlara ayrı, sunucuda üretilmiş sürümUzun vadeli çözüm değil, geçici bir çözüm (workaround)

Dinamik render: neden artık önerilmiyor?

Dinamik render'da sunucu, user-agent'a bakarak botları tespit eder ve onlara JavaScript'siz, sunucuda üretilmiş bir sürüm sunarken kullanıcılara istemci taraflı sürümü gösterir. Google bu yöntemi açıkça “geçici bir çözüm” olarak tanımlıyor ve ek karmaşıklık ve kaynak gerektirdiği için önermiyor; onun yerine sunucu taraflı render, statik render veya hydration öneriyor.

Dinamik render kullanan mevcut siteler için iyi haber: Googlebot, benzer içerik üretildiği sürece dinamik render'ı genellikle gizleme (cloaking) saymıyor. Ancak kullanıcılara ve tarayıcılara tamamen farklı içerik sunmak (kullanıcıya kedi, bota köpek sayfası) gizleme sayılabilir. Gizleme ve diğer politikalar için Google spam politikaları rehberimize bakın.

Linkler: Google yalnızca href’li a etiketlerini takip eder

Google'ın link belgesine göre Google genellikle yalnızca href niteliği olan <a> elemanlarını tarayabilir. JavaScript ile DOM'a link eklemek sorun değil, yeter ki bu linkler aynı HTML biçiminde olsun. Karşılaştırma:

html
<!-- Google ayrıştırabilir -->
<a href="/urunler/ayakkabi">Ayakkabılar</a>
<a href="/urunler/ayakkabi" onclick="javascript:goTo('ayakkabi')">Ayakkabılar</a>

<!-- Önerilmez (Google yine de denemeye çalışabilir) -->
<a routerLink="urunler/ayakkabi">Ayakkabılar</a>
<span href="https://ornek.com">Ayakkabılar</span>
<a onclick="goto('https://ornek.com')">Ayakkabılar</a>

URL parçası (#) yerine History API

Tek sayfalık uygulamalarda farklı görünümleri #/urunler gibi URL parçalarıyla yüklemek, Googlebot'un URL'leri güvenilir şekilde çözememesine yol açar. Google, AJAX tarama şemasının 2015'ten beri kullanımdan kaldırıldığını hatırlatıyor ve istemci taraflı yönlendirme için History API kullanmanızı öneriyor:

html
<nav>
  <a href="/urunler">Ürünlerimiz</a>
  <a href="/hizmetler">Hizmetlerimiz</a>
</nav>
<div id="icerik"></div>
<script>
function sayfayaGit(olay) {
  olay.preventDefault();
  const url = olay.target.getAttribute('href');
  document.getElementById('icerik').innerHTML = yukle(url.slice(1));
  window.history.pushState({}, document.title, url);
}
document.querySelectorAll('nav a').forEach(a => a.addEventListener('click', sayfayaGit));
</script>

Site içi link yapısının stratejik tarafı için site içi linkleme rehberimize göz atın.

Başlık, açıklama, canonical ve robots meta

Başlık, açıklama, canonical ve robots meta: Canonical, noindex, Yapılandırılmış veri

JavaScript ile <title> ve meta açıklamayı ayarlamak veya değiştirmek mümkün. Benzersiz, açıklayıcı başlıklar için başlık ve meta açıklama rehberimize bakın. Canonical ve robots meta tarafında ise Google'ın daha katı kuralları var:

  • Canonical: En iyi yol HTML'de belirtmek. JavaScript kullanmak zorundaysanız canonical'ı her zaman orijinal HTML'dekiyle aynı değere ayarlayın. HTML'de belirtemiyorsanız orijinal HTML'den tamamen çıkarıp yalnızca JavaScript ile ekleyin. Sayfada tek bir rel="canonical" olduğundan emin olun; birden fazla veya çelişen canonical beklenmedik sonuçlar doğurabilir.
  • noindex: JavaScript ile robots meta etiketi eklenebilir veya değiştirilebilir. Ama Google noindex gördüğünde render'ı atlayabildiği için, orijinal HTML'deki noindex'i JavaScript ile kaldırmak beklendiği gibi çalışmayabilir. Sayfanın dizine girmesini istiyorsanız orijinal kodda noindex kullanmayın.
  • Yapılandırılmış veri: JSON-LD'yi JavaScript ile üretip sayfaya eklemek mümkün; mutlaka test edin. Google, alışveriş sonuçları için Product işaretlemesini en iyi sonuç için ilk HTML'de vermenizi öneriyor. Ayrıntılar JSON-LD rehberimizde.

Canonical konusunun tamamı için canonical etiketi rehberimize, noindex için meta robots rehberimize bakabilirsiniz.

SPA’larda soft 404 sorunu

İstemci taraflı yönlendirme yapan SPA'larda hata durumları genellikle JavaScript ile ele alınır ve sunucu her URL için 200 döndürür. Google bunun hata sayfalarının dizine eklenip arama sonuçlarında görünmesine yol açabileceğini belirtiyor. Google'ın önerdiği iki strateji var; birini veya ikisini birlikte kullanabilirsiniz:

1. Sunucunun 404 döndürdüğü bir URL'ye JavaScript yönlendirmesi:

javascript
fetch(`/api/urunler/${urunId}`)
  .then(yanit => yanit.json())
  .then(urun => {
    if (urun.exists) {
      urunDetayiniGoster(urun);
    } else {
      window.location.href = '/bulunamadi'; // sunucu bu URL için 404 döndürür
    }
  });

2. Hata sayfasına JavaScript ile noindex eklemek:

javascript
fetch(`/api/urunler/${urunId}`)
  .then(yanit => yanit.json())
  .then(urun => {
    if (!urun.exists) {
      const metaRobots = document.createElement('meta');
      metaRobots.name = 'robots';
      metaRobots.content = 'noindex';
      document.head.appendChild(metaRobots);
    }
  });

Durum kodlarının Google için anlamını HTTP durum kodları yazımızda bulabilirsiniz. Mümkün olduğunda anlamlı durum kodu kullanın: bulunamayan sayfa için 404, giriş gerektiren sayfa için 401.

Lazy loading ve sonsuz kaydırma

Lazy loading iyi bir performans uygulaması, ama yanlış kurulursa içeriği Google'dan gizleyebilir. Google'ın kuralı basit: içerik görüntü alanına (viewport) girdiğinde yüklenmeli. Google Arama sayfanızla etkileşime girmez; kaydırma veya tıklama gibi kullanıcı eylemlerine bağlı yükleme yapan çözümler içeriği gizleyebilir. Google'ın saydığı uygun yöntemler: tarayıcının yerleşik lazy loading'i (görseller ve iframe'ler için), IntersectionObserver API ve içeriği görüntü alanına girdiğinde yükleyen bir JavaScript kütüphanesi.

html
<img src="/gorseller/sunucu.webp" loading="lazy" alt="Sunucu odası" width="800" height="450">

Sayfa açıldığında hemen görünecek içeriğe lazy loading eklemeyin; Google bunun içeriğin geç görünmesine yol açacağını belirtiyor. Görsel tarafı için görsel optimizasyonu rehberimize bakın.

Sonsuz kaydırmayı dizine eklenebilir yapmak için Google şunları öneriyor: her parçaya kalıcı ve benzersiz bir URL verin, ?page=12 gibi mutlak sayfa numaraları kullanın (?date=yesterday gibi göreli değerlerden kaçının), parçalara sıralı linkler verin ve kullanıcı yeni parçaya geldiğinde History API ile görünen URL'yi güncelleyin.

Googlebot’un bilmeniz gereken sınırlamaları

Googlebot’un bilmeniz gereken sınırlamaları: İzin istekleri (kamera vb.), localStorage, sessionStorage, çerezler, Önbellekleme, WebSockets, WebRTC
DurumGoogle ne diyorNe yapmalı
İzin istekleri (kamera vb.)Googlebot kullanıcı izin isteklerini reddederİçeriğe izin vermeden erişim yolu sunun
localStorage, sessionStorage, çerezlerSayfa yüklemeleri arasında temizlenir; durum korunmazİçerik sunmak için kalıcı veriye güvenmeyin
ÖnbelleklemeGooglebot agresif önbellekler; WRS önbellek başlıklarını yok sayabilirmain.2bb85551.js gibi içerik parmak izli dosya adları kullanın
WebSockets, WebRTCDesteklenmez; Googlebot HTTP istekleri kullanırİçerik için HTTP yedeği sağlayın
WebGL gibi özelliklerÖzellik algılama Googlebot’un WebGL desteklemediğini gösterirÖzellik algılama ve yedek davranış veya sunucuda ön render
Web bileşenleri (shadow DOM)Google light ve shadow DOM’u düzleştirir; yalnızca render edilmiş HTML’de görünen içeriği görür&lt;slot&gt; mekanizmasını kullanın ve render edilmiş HTML’yi kontrol edin
JavaScript tabanlı ödeme duvarıTam içeriği sunucuda gönderip JS ile gizlemek güvenilir bir kısıtlama değildirTam içeriği yalnızca abonelik doğrulandıktan sonra sunun

Google ayrıca Googlebot ve render servisinin (WRS), raporlama ve hata istekleri gibi asıl içeriğe katkı sağlamayan kaynakları getirmeyebileceğini belirtiyor. Bu yüzden istemci taraflı analitik araçlar Googlebot etkinliğini tam göstermeyebilir; bunun için Search Console'daki “Crawl Stats” raporunu kullanın. Bu rapor ve tarama kapasitesi için tarama bütçesi rehberimize bakın.

URL Denetimi ve Zengin Sonuç Testi ile test

Google'ın önerdiği ilk adım, sayfayı Zengin Sonuç Testi veya Search Console'daki URL Denetimi aracıyla test etmek. Bu araçlarda yüklenen kaynakları, JavaScript konsol çıktısını ve istisnaları, render edilmiş DOM'u görebilirsiniz. Kontrol listesi:

  • Render edilmiş HTML'de ana içerik metni var mı?
  • Linkler render edilmiş HTML'de <a href> olarak görünüyor mu?
  • Lazy loading görsellerinin URL'leri render edilmiş HTML'de <img> elemanının src niteliğinde görünüyor mu? Google'a göre görünüyorsa kurulumunuz doğru çalışıyor.
  • Canonical ve robots meta etiketleri beklediğiniz değerde ve tek mi?
  • Konsolda içerik yüklemesini engelleyen hata var mı? Engellenmiş (robots.txt) kaynak var mı?

Google ayrıca kullanıcıların ve Googlebot'un karşılaştığı JavaScript hatalarını window.addEventListener('error', ...) ile toplayıp kaydetmeyi isteğe bağlı bir öneri olarak sunuyor. Parse hataları gibi bazı hata türlerinin bu yöntemle yakalanamayacağını unutmayın. URL Denetimi aracındaki diğer durumların anlamı için dizine eklenmedi hataları rehberimize bakın. Not: Search Console arayüzündeki Türkçe etiketler, bu yazıda parantez içinde verdiğimiz karşılıklardan biraz farklı olabilir. Emin olmadığımız yerlerde İngilizce orijinal adı tırnak içinde kullandık.

Sık Sorulan Sorular

Google JavaScript ile eklenen içeriği dizine ekler mi?

Evet, Google 200 durum kodlu sayfaları render eder ve render edilmiş HTML'yi dizine ekleme için kullanır. Ancak render kuyruğunda bekleme olabilir, bazı tarayıcı özellikleri desteklenmez ve diğer arama motorları JavaScript'i çalıştırmayabilir. Bu yüzden Google kritik içerik için sunucu taraflı veya ön render'ı hâlâ iyi bir fikir olarak görüyor.

Dinamik render kullanmak ceza sebebi mi?

Google, benzer içerik sunulduğu sürece dinamik render'ı genellikle gizleme saymıyor. Ancak artık geçici bir çözüm olarak görüyor ve yeni projelerde sunucu taraflı render, statik render veya hydration öneriyor.

SPA’mda olmayan ürün sayfaları neden dizinde görünüyor?

Büyük olasılıkla sunucu bu URL'ler için 200 döndürüyor ve hata JavaScript ile gösteriliyor. Google'ın önerdiği iki çözümden birini uygulayın: sunucunun 404 döndürdüğü bir URL'ye yönlendirme veya hata durumunda JavaScript ile noindex ekleme.

Orijinal HTML’de noindex var, JavaScript ile kaldırıyorum. Çalışır mı?

Güvenilir değil. Google noindex gördüğünde render'ı atlayabilir; bu yüzden JavaScript'in etiketi kaldırdığını hiç görmeyebilir. Dizine girmesini istediğiniz sayfalarda orijinal kodda noindex kullanmayın.

İlgili içerikler: JavaScript nedir? · Canonical etiketi · Dizine eklenmedi hataları · Tarama bütçesi · Meta robots etiketi · Core Web Vitals · Teknik SEO nedir?