React, Vue veya Angular ile kurulmuş bir site başlangıçta tam anlamıyla çalışıyor gibi görünebilir. Kullanıcı deneyimi akıcı, geçişler hızlı, sayfa yüklemeleri pürüzsüz. Ama Google Search Console’u açtığınızda tablo farklı: sayfaların önemli bir kısmı indexlenmemiş, içerikler Google tarafından görülmüyor, sorgu görünürlüğü beklenenin çok altında.
Bu durum JavaScript SEO’nun en yaygın senaryosu. Geliştiriciler için sorunsuz çalışan bir uygulama, Googlebot için oldukça zorlu bir içerik olabilir.
Bu rehberde JavaScript SEO’nun ne olduğunu, neden sorun çıkardığını, rendering stratejilerinin (CSR, SSR, SSG, ISR) SEO üzerindeki etkilerini ve pratik çözüm yollarını ele alıyorum. Teknik SEO’nun genel çerçevesi için teknik SEO rehberimize bakabilirsiniz.
JavaScript SEO nedir?
JavaScript SEO, JavaScript ile oluşturulmuş web içeriklerinin arama motorları tarafından doğru biçimde taranması, anlaşılması ve indexlenmesi için yapılan optimizasyon çalışmalarıdır.
Problem şu: Google sayfaları iki aşamada işliyor.
- İlk tarama: Googlebot sayfayı HTML olarak indiriyor. Bu aşamada JavaScript henüz çalıştırılmamış; sayfa görünür içerik yerine boş veya kısmen dolu bir iskelet.
- Rendering kuyruğu: Google, JavaScript’i çalıştırıp sayfayı tam haliyle görmek için ikinci bir aşamada kaynakları işliyor. Bu aşama günler, hatta haftalar sürebilir. Kapasite kısıtlı olduğundan her sayfa önceliklendirilemiyor.
Bu iki aşamalı süreç, JavaScript ağırlıklı sitelerde ciddi indexleme gecikmeleri ve eksikliklerine yol açıyor.
Rendering stratejileri ve SEO etkisi
Client-Side Rendering (CSR)
Tarayıcı boş bir HTML alıyor ve JavaScript çalıştırıldıktan sonra içerik oluşturuluyor. Geleneksel React uygulamalarının varsayılan davranışı.
SEO etkisi: En sorunlu yaklaşım. Googlebot ilk taramada boş sayfa görüyor. Rendering kuyruğuna giriyor ama bu süre belirsiz. İçerikler geç indexleniyor, bazıları hiç indexlenmiyor. LCP süresi uzuyor; Core Web Vitals puanı düşüyor.
Ne zaman kullanılır: Dahili paneller, giriş gerektiren sayfalar, SEO önemsiz uygulamalar için kabul edilebilir.
Server-Side Rendering (SSR)
Her istek için sunucu, tam HTML’i oluşturup gönderiyor. Kullanıcı ve Googlebot aynı, hazır HTML’i alıyor.
SEO etkisi: CSR’ye kıyasla çok daha iyi. Googlebot ilk taramada tam içeriği görüyor, iki aşamalı bekleme yok. LCP süresi de iyileşiyor; sunucu hazır HTML gönderdiği için tarayıcı anında içeriği gösterebiliyor.
Dezavantajı: Her istekte sunucu yük alıyor. Yüksek trafikli sitelerde TTFB artabilir; önbellekleme stratejisi kritik önem kazanıyor.
Ne zaman kullanılır: Dinamik içerik gerektiren, kişiselleştirme içeren veya sık değişen SEO-kritik sayfalar.
Static Site Generation (SSG)
Derleme aşamasında tüm sayfalar önceden HTML olarak üretiliyor. Kullanıcı ve Googlebot statik HTML alıyor; sunucu işlemi yok.
SEO etkisi: En iyi seçenek. Hazır HTML, hızlı TTFB, düşük LCP, sorunsuz indexleme. Core Web Vitals açısından da avantajlı.
Dezavantajı: İçerik değiştiğinde yeniden derleme gerekiyor. Binlerce sayfalı e-ticaret siteleri veya sık güncellenen içerikler için derleme süresi sorun yaratabilir.
Ne zaman kullanılır: Blog, kurumsal site, portföy gibi sık değişmeyen içerik ağırlıklı siteler. Bu sitenin Astro tabanlı yapısı SSG’yi merkeze alıyor; SEO açısından bu tercih doğru.
Incremental Static Regeneration (ISR)
Next.js’in geliştirdiği hibrit yaklaşım. Sayfalar statik olarak üretiliyor ama belirli aralıklarla arka planda yenileniyor. Yenileme süresi dolmadan gelen istekler mevcut statik versiyonu alıyor; süre dolduğunda sayfa yeniden üretiliyor.
SEO etkisi: SSG’nin avantajlarını dinamik içeriklerle birleştiriyor. E-ticaret ürün sayfaları, haber siteleri ve blog arşivleri için ideal denge.
Ne zaman kullanılır: Düzenli güncellenen ama her istekte sunucu işlemi gerektirmeyen SEO-kritik sayfalar.
Rendering kararı nasıl verilir?
Her site tek bir rendering stratejisi kullanmak zorunda değil. Sayfa türüne göre karma yaklaşım çoğunlukla en iyisi:
| Sayfa Türü | Önerilen Yaklaşım |
|---|---|
| Blog yazıları | SSG veya ISR |
| Ana sayfa | SSG |
| Ürün listesi | ISR |
| Kullanıcı dashboard | CSR (giriş gerektiriyor, SEO yok) |
| Kategori sayfaları | SSG veya ISR |
| Arama sonuçları | SSR |
| Kampanya landing page | SSG |
Bu tabloya göre Next.js veya Nuxt.js ile hibrit mimari kurabilirsiniz: bazı rotalar SSG, bazıları SSR, bazıları CSR.
JavaScript SEO denetimi: nelere bakılır?
Google’ın sayfayı nasıl gördüğünü test edin
Google Search Console → URL Denetimi: İncelemek istediğiniz URL’i girin. “Sayfa Getir” seçeneğiyle Googlebot’un o sayfayı nasıl gördüğünü anlık test edebilirsiniz. JavaScript render edilmiş versiyon görünüyorsa içerik erişilebilir demek.
Rich Results Test: search.google.com/test/rich-results adresinde de sayfa getirme yapılabiliyor. Render edilmiş HTML’i ve varsa schema hatalarını gösteriyor.
Render karşılaştırması
Sayfanın kaynak kodunu (Ctrl+U) ve tarayıcının oluşturduğu DOM’u (F12 → Elements) karşılaştırın. Kaynak kodda olmayan ama DOM’da olan içerikler JavaScript ile yükleniyor demek. Bu içeriklere Googlebot geç erişiyor.
Indexleme durumu
Search Console’da “Sayfalar” raporunu açın. “Dizine eklenmedi” kategorisindeki URL’leri inceleyin. “Tarandı - şu an dizine eklenmedi” ve “Keşfedildi - şu an dizine eklenmedi” durumları JavaScript rendering gecikmesine işaret edebiliyor.
Crawl bütçesi analizi
Search Console’da “Ayarlar → Tarama istatistikleri” bölümünde Googlebot’un siteyi nasıl taradığını görebilirsiniz. JavaScript ağırlıklı sayfalarda tarama başarı oranı ve tarama hızı düşükse sorun var.
Yaygın JavaScript SEO sorunları ve çözümleri
1. Dinamik iç linkler indexlenmez
Sorun: Menü, breadcrumb veya kategori bağlantıları JavaScript ile oluşturuluyor. Googlebot ilk taramada bu linkleri görmüyor; sayfalara ulaşamıyor.
Çözüm: Navigasyon ve iç bağlantıları HTML’de statik olarak oluşturun. JavaScript ile dinamik zenginleştirme yapabilirsiniz ama temel link yapısı HTML’de olmalı. Özellikle <a href="..."> etiketleri JavaScript event listener ile değil, gerçek HTML bağlantısı olarak kurulmalı.
2. Lazy-loaded içerik görünmez
Sorun: Sayfanın alt kısmındaki içerikler kaydırma ile yükleniyorsa Googlebot bunları görmeyebiliyor. Intersection Observer ile tetiklenen içerikler risk altında.
Çözüm: SEO-kritik içerikleri lazy load dışında tutun. Görseller lazy load için uygun ama metinsel içerik ve önemli bağlantılar sayfa yüklemesinde mevcut olmalı.
3. Meta tag’lar JavaScript ile değiştiriliyor
Sorun: Sayfa başlığı, meta description veya canonical URL, JavaScript çalıştıktan sonra değiştiriliyor. İlk HTML’de varsayılan değer var; JavaScript render edildikten sonra doğru değer geliyor.
Çözüm: Meta tag’ları SSR veya SSG ile sunucu tarafında oluşturun. Client-side değişiklik ikincil olabilir ama birincil değer HTML’de olmalı.
4. Infinite scroll ve paginated içerik
Sorun: Sayfa kaydırıldıkça yeni içerik yükleniyor. Googlebot bu içeriğe ulaşamıyor; yalnızca ilk yüklenen bölümü indexliyor.
Çözüm: Geleneksel sayfalandırma (pagination) kullanın veya “Daha fazla göster” butonu ekleyin. Alternatif: her sayfa grubunu ayrı URL olarak yapılandırın (/blog?page=2).
5. JavaScript tabanlı yönlendirmeler
Sorun: window.location veya history API ile yapılan yönlendirmeler Googlebot tarafından bazen atlanıyor.
Çözüm: Yönlendirmeler için her zaman sunucu tarafı 301 veya 302 HTTP yönlendirmelerini kullanın. JavaScript yönlendirme yalnızca kullanıcı arayüzü geçişleri için kabul edilebilir.
6. Single Page Application (SPA) URL yapısı
Sorun: SPA’larda sayfa geçişleri URL değiştirmiyor veya hash tabanlı URL kullanıyor (example.com/#/hakkimizda). Google bu URL’leri ayrı sayfa olarak indexlemiyor.
Çözüm: HTML5 History API ile düzgün URL yapısı kurun (example.com/hakkimizda). Hash tabanlı yönlendirmeden kaçının. Her SPA rotası için sunucu tarafında karşılık gelen URL yapılandırılmalı.
Framework bazlı öneriler
Next.js
Next.js sayfa bazlı rendering kararı verme esnekliği sunuyor.
// SSG - derleme zamanında üretim
export async function getStaticProps() {
const data = await fetchData();
return { props: { data } };
}
// SSR - her istekte sunucu işlemi
export async function getServerSideProps() {
const data = await fetchData();
return { props: { data } };
}
// ISR - periyodik yenileme
export async function getStaticProps() {
const data = await fetchData();
return { props: { data }, revalidate: 3600 }; // 1 saatte bir yenile
}
SEO-kritik sayfalar için getStaticProps veya getStaticProps + revalidate, dinamik ve kişiselleştirilmiş içerik için getServerSideProps.
Astro
Astro varsayılan olarak sıfır JavaScript gönderiyor; component’lar yalnızca gerektiğinde hydrate ediliyor. Bu yaklaşım JavaScript SEO sorunlarının büyük bölümünü başlangıçta ortadan kaldırıyor.
// .astro dosyasının üst kısmı (derleme zamanı)
import { getCollection } from "astro:content";
const posts = await getCollection("blog");
// Aşağıdaki JSX benzeri şablon aynı dosyada HTML üretir (isteğe bağlı island'lar hariç ek JS yok)
Astro tabanlı siteler için JavaScript SEO sorunu büyük ölçüde sınırlı; dikkat edilmesi gereken: Astro Islands ile eklenen client-side componentlerin içerik için değil, etkileşim için kullanılması.
React (Create React App / Vite)
Saf CSR React uygulamaları SEO için en riskli seçenek. Bu yapıları SSR veya SSG’ye taşımak için Next.js veya Remix’e geçiş düşünülebilir. Mevcut uygulamayı değiştirememek için ara çözüm olarak prerendering servisleri (Prerender.io, Rendertron) kullanılabilir ama uzun vadeli çözüm değil.
Vue / Nuxt
Nuxt, Next.js’e benzer SSR/SSG/ISR hybrid yapı sunuyor. Vue uygulamasının SEO tarafını güçlendirmenin en hızlı yolu Nuxt’a geçiş.
Core Web Vitals ve JavaScript
JavaScript SEO ve Core Web Vitals sıkı biçimde bağlantılı. CSR yaklaşımı neredeyse her zaman:
- LCP süresini uzatıyor: tarayıcı önce boş HTML alıyor, JS çalışana kadar ana içerik görünmüyor.
- INP’i olumsuz etkiliyor: büyük JS bundle’lar uzun görevler oluşturuyor, etkileşim gecikmesi artıyor.
- CLS’yi artırıyor: JS ile yüklenen içerikler yerleşince layout kayması yaşanıyor.
SSR ve SSG bu üç metriği aynı anda iyileştiriyor. Core Web Vitals rehberimiz optimizasyon adımlarını detaylandırıyor.
JavaScript SEO kontrol listesi
Temel kontroller:
- Googlebot sayfayı tam içerikle görüyor mu? (URL Denetimi ile test edin)
- Meta title, description ve canonical HTML’de statik olarak mevcut mu?
- Tüm iç bağlantılar
<a href>etiketiyle HTML’de mevcut mu? - SEO-kritik içerik JavaScript olmadan görünür mü?
Rendering kontrolü:
- Her sayfa türü için doğru rendering stratejisi seçildi mi?
- SSG veya SSR uygulanan sayfalarda sunucu HTML’i tam içerik sunuyor mu?
- Pagination veya “daha fazla” içeriği ayrı URL’lerle erişilebilir mi?
Performans kontrolü:
- LCP 2,5 saniye altında mı?
- Gereksiz JS bundle’lar code splitting ile bölündü mü?
- Üçüncü taraf scriptler defer/async ile yükleniyor mu?
Sıkça Sorulan Sorular
Google artık JavaScript’i tam okuyabiliyor, sorun kaldı mı?
Google’ın rendering kapasitesi gelişti ama iki aşamalı süreç hâlâ geçerli. İlk tarama HTML tabanlı, rendering sıraya giriyor. Bu gecikme özellikle yeni sayfalar ve sık güncellenen içerikler için ciddi indexleme sorunu yaratıyor. “Google artık JS okuyabiliyor” yanılgısı hâlâ yaygın bir hata.
SPA’dan SSR/SSG’ye geçiş ne kadar karmaşık?
Uygulamanın büyüklüğüne ve mimarisine bağlı. Küçük projeler için Next.js veya Nuxt geçişi birkaç haftada tamamlanabiliyor. Büyük ve köklü uygulamalar için kademeli geçiş (önce kritik sayfalar, sonra geri kalan) daha gerçekçi. Prerendering servisleri geçiş sürecinde geçici köprü işlevi görebilir.
Next.js kullanan bir site JavaScript SEO sorunu yaşar mı?
Eğer getStaticProps veya getServerSideProps doğru kullanılıyorsa büyük ölçüde hayır. Ama geliştiriciler CSR modunda component yazmaya devam ederse (useEffect içinde veri çekme, client-side fetch) sorunlar devam edebilir. Framework seçimi tek başına yeterli değil; doğru pattern uygulamak gerekiyor.
Prerendering araçları ne kadar güvenilir?
Prerender.io ve benzeri araçlar Googlebot isteğini tespit edip önceden render edilmiş HTML gönderiyor. Geçici çözüm olarak işe yarıyor ama Google bu yaklaşımı “cloaking benzeri” bulabiliyor; dikkatli kullanılmalı. Uzun vadeli çözüm değil.
Astro ile JavaScript SEO sorunu yaşanır mı?
Astro’nun statik üretim odaklı yaklaşımı büyük ölçüde JavaScript SEO sorununu baştan önlüyor. Client-side JavaScript yalnızca Islands architecture ile ekleniyor ve kontrollü. Bu site Astro kullandığı için JavaScript SEO riskleri minimum seviyede.
CSR sitemi SSR’ye taşımak zorunda mıyım?
“Zorunda” değilsiniz ama SEO hedefliyorsanız güçlü önerilir. Eğer siteniz tamamen login gerektiren, SEO önemsiz bir uygulama ise CSR sorun değil. Organik trafik hedefliyorsanız SSR veya SSG kaçınılmaz.
JavaScript’te iç link kurmak için özel bir yöntem var mı?
Temel kural: iç bağlantılar <a href="/hedef-sayfa"> şeklinde HTML’de olmalı. React Router veya Vue Router’ın <Link> veya <router-link> componentleri bu kurala uygun; sonuçta HTML <a> etiketi üretiyorlar. JavaScript event listener ile gezinti yapan ancak <a href> kullanmayan yapılardan kaçının.
Sonuç
JavaScript SEO, modern web geliştirmenin kaçınılmaz bir kesişim noktası. “İyi çalışan uygulama” ile “Google’ın düzgün indexlediği site” aynı şey değil; ikisini aynı anda sağlamak mimari kararlarla mümkün.
Üç maddede özetlemek gerekirse:
- SEO-kritik sayfalar için SSG veya SSR seçin; CSR yalnızca SEO önemsiz bölümler için.
- Googlebot’un sayfayı nasıl gördüğünü düzenli aralıklarla URL Denetimi ile test edin.
- İç bağlantıları, meta tag’ları ve kritik içerikleri HTML’de statik olarak sunun; JavaScript’e bırakmayın.
Teknik SEO’nun diğer boyutlarını görmek için teknik SEO rehberi ve Core Web Vitals rehberi iyi kaynaklar. Sitenizin JavaScript SEO durumunu analiz etmek için ücretsiz SEO danışmanlığı teklifi alabilirsiniz.