Angular'da SEO

Angular uygulamalarını taranabilir ve dizine eklenebilir hâle getirme: @angular/ssr ile önceden oluşturma ve hibrit oluşturma karşılaştırması, hydration, Title/Meta servisleri, History API yönlendirmesi ve Googlebot'un gerçekten oluşturduğu içeriği test etme.

İlk yayın tarihi: 26 Haz 2026 · Son güncelleme: 22 Ağu 2026 · Advanced
Diller

Angular'da SEO aslında tek bir karardır: istemci tarafından oluşturulan bir kabuk yerine gerçek HTML sunmak. Modern Angular (v17+) SSR'yi @angular/ssr olarak CLI'ye yerleşik getirir; statik rotaları önceden, dinamikleri sunucuda oluşturun, hibrit yapı kullanın ve sunucu HTML'si yeniden oluşturulmak yerine yeniden kullanılsın diye hydration uygulayın. Ardından temel işleri tamamlayın: Angular'ın Title ve Meta servisleriyle benzersiz başlık ve açıklamalar, HTML5 History yönlendirmesi (hash URL'ler asla değil), gerçek <a href> bağlantıları ve URL Inspection ile doğrulama. Dinamik oluşturma bir strateji değil, geçici bir çözümdür; AngularJS ise farklı bir çerçevedir.

TL;DR — Angular SEO, birçok rol üstlenen tek bir mimari karardır: istemci kabuğu yerine yanıta gerçek HTML koyun. Modern Angular (v17+), yeniden adlandırılmış ve bütünleşik Angular Universal halefi olan @angular/ssr ile SSR’yi CLI’ye ekler. Statik rotaları önceden, dinamikleri sunucuda oluşturun; hibrit oluşturmayla ikisini birleştirin ve sunucu HTML’si yeniden oluşturulmak yerine kullanılsın diye hydration uygulayın. Ardından Title/Meta servisleri (veya yönlendiricinin TitleStrategy’si) ile benzersiz başlık/açıklamalar, HTML5 History yönlendirmesi — HashLocationStrategy asla değil — gerçek <a href> bağlantıları, güvenli JSON-LD ve URL Inspection doğrulaması ekleyin. Dinamik oluşturma, Google’ın kabul ettiği bir geçici çözümdür; strateji değildir.

Evidence for this claim Modern Angular documents @angular/ssr as its server-side and hybrid rendering package. Scope: Current Angular documentation; historical Angular Universal details are not required for this claim. Confidence: high · Verified: Angular: Server-side and hybrid rendering

Varsayılan sorun: istemci taraflı oluşturma

Standart bir Angular derlemesi, gövdesi esasen <app-root></app-root> öğesiyle komut dosyası etiketlerinden oluşan bir index.html gönderir. JavaScript çalıştırılmadığında tarayıcı botu hiçbir başlık, metin veya bağlantı göremez; içerik, paket yüklendikten sonra tarayıcıda oluşturulur. Bu, JavaScript SEO yazısında anlattığım temel sorunla aynıdır: Web, düz HTML’den uzaklaştı ve CSR bu yelpazenin en riskli ucudur.

(Bu rehberin uygulama ayrıntıları — RenderMode API’leri, hydration tetikleyicileri ve event replay — Angular v22’yi yansıtır. Aşağıdaki sürüme özgü özellikler tarihlidir: v17 SSR yeniden adlandırması, v18 event replay ve v19–v20 artımlı hydration.)

CSR üç farklı SEO sorunu oluşturur:

  1. Gecikmiş ve daha az güvenilir dizine ekleme. Google, JS uygulamalarını üç aşamada işler — “Tarama, Oluşturma ve Dizine Ekleme” — ve oluşturma işlemi bir kuyruğa ertelenir. Bu oluşturma işlemi gerçekleşene kadar içeriğiniz dizine eklenmek üzere mevcut değildir.
  2. Daha kötü Core Web Vitals. Tarayıcının anlamlı içeriği görüntülemeden önce bir paketi indirip çalıştırması gerektiğinden LCP olumsuz etkilenir.
  3. Google dışındaki tarayıcı botları kabuğu görür. Bingbot, JS oluşturma konusunda çok daha tutarsızdır; sosyal medya ve bağlantı önizleme botları ise genellikle hiç oluşturma yapmaz. Bu nedenle istemci tarafında eklenen Open Graph etiketleri ve içerik onlara ulaşmaz.

Googlebot bir Angular uygulamasını gerçekte nasıl işler?

Googlebot evergreen’dir; Chrome’un güncel V8 motor sürümüyle oluşturur ve Chrome sürümleriyle birlikte güncellenir. Evidence for this claim Googlebot uses an evergreen version of Chromium for rendering. Scope: Google Search rendering engine; this does not remove application-level rendering risks. Confidence: high · Verified: Google: Evergreen Googlebot Bu nedenle Angular’ı çalıştırabilir; ancak tasarımda hesaba katılması gereken sert sınırlar vardır:

  • Oluşturma kuyruğa alınır, anında yapılmaz. Google ayrı tarama, oluşturma ve dizine ekleme aşamalarını belgeler; oluşturmanın taramaya yetişmesinin ne kadar sürdüğüne dair sabit bir takvim yayımlamaz. Sektörün “iki dalga” dediği şey budur: önce ham HTML (CSR Angular için boş kabuk), oluşturma çalıştığında daha sonra oluşturulmuş DOM dizine eklenir. SSR/önceden oluşturma beklemeyi ortadan kaldırır; ilk getirmede HTML tamamdır.
  • Oluşturucu durumsuzdur. Yüklemeler arasında çerez, localStorage veya sessionStorage taşımaz; izin istemlerini reddeder. İçeriği istemci durumuna bağlamayın.
  • Tıklamaz veya kaydırmaz ve çok uzun bir görüntü alanında oluşturur. Etkileşimin arkasındaki içerik görülmez.
  • Kaynaklar agresif biçimde önbelleğe alınır — güncellenmiş paketlerin eski sunulmaması için içerik parmak izli dosya adları (Angular’ın varsayılanı main.<hash>.js) kullanın.

@angular/ssr — nedir, adlandırma geçmişi

Sunucu taraflı oluşturma Angular’ı her istek için bir Node sunucusunda çalıştırır ve tarayıcının ardından hydrate ettiği (yeniden oluşturmak yerine mevcut DOM’a olay dinleyicileri eklediği) tam oluşturulmuş HTML döndürür. Googlebot, Bingbot ve sosyal botlar ikinci dalgaya gerek kalmadan ilk istekte tam HTML alır.

Adlandırma sık karıştırılıyor; bu yüzden net olalım: “Angular Universal” tarihî SSR çözümüydü ve harici bir paket (@nguniversal/express-engine) olarak dağıtılıyordu. Angular v17 (Kasım 2023) ile SSR doğrudan Angular CLI ve Application Builder’a entegre edildi ve @angular/ssr olarak yeniden adlandırıldı; Angular Universal deposu artık bakım modunda. Evidence for this claim Modern Angular documents @angular/ssr as its server-side and hybrid rendering package. Scope: Current Angular documentation; historical Angular Universal details are not required for this claim. Confidence: high · Verified: Angular: Server-side and hybrid rendering Kurulum artık tek satırdır:

# New project with SSR enabled
ng new my-app --ssr

# Add SSR to an existing project
ng add @angular/ssr

Bu, eski ng add @nguniversal/express-engine komutunun yerini alır. Fikir aynıdır; artık Angular tarafından doğrudan desteklenen araçlarla sunulur.

Önceden oluşturma (statik üretim / SSG)

Önceden oluşturma, rotalar için derleme zamanında statik HTML üretir; bu nedenle istek sırasında sunucu çalışmaz — CDN’e dağıtabilirsiniz. En hızlı TTFB/FCP/LCP’yi ve en düşük işletim maliyetini sağlar. v17+ sürümlerinde bunu bir sunucu rotaları dosyasında (app.routes.server.ts) RenderMode.Prerender ile rota bazında yapılandırırsınız; outputMode: 'static' tamamen statik bir uygulama üretir.

Kısıt şudur: Veriler derleme zamanında mevcut olmalı, kullanıcıya özel içerik bulunmamalı ve çok büyük siteler yavaş derlemeler anlamına gelir. Bu yöntem pazarlama sayfaları, belgeler ve blog yazıları için idealdir — tam da sıralanması ve kaynak gösterilmesi en çok gereken içerik.

Hibrit oluşturma — rota başına bir mod seçin

v17+ ile gelen büyük yenilik, oluşturma modunun app.routes.server.ts içinde yapılandırılan rota başına bir karar olmasıdır:

  • RenderMode.Prerender — statik rotalar (ana sayfa, hakkında, blog yazıları).
  • RenderMode.Server — dinamik, istek başına rotalar (arama sonuçları, güncel verili panolar).
  • RenderMode.Client — zaten dizine eklenmesini istemediğiniz yalnızca iç rotalar (yönetim arayüzleri, yalnızca kimlik doğrulamalı ekranlar). CSR burada gerçekten uygundur.

Pratik karar kuralı şudur: statik olanı önceden oluşturun, güncel kalması gerekeni sunucuda oluşturun ve yalnızca dizinde bulunmaması gereken şeylerde istemci taraflı oluşturmaya dönün.

Hydration — CLS’yi bozan tuzak

Naif SSR’nin bir kusuru vardır: sunucu HTML’yi gönderir, ardından tarayıcı onu atıp baştan oluşturur; bu da bir titreme ve boşa giden iş yaratır. Hydration bunu düzeltir: tarayıcı sunucuda oluşturulan uygulamayı geri yükler ve eşleşen DOM’u yok edip yeniden oluşturmak yerine yalnızca etkileşimi bağlar. app.config.ts içinde etkinleştirin:

provideClientHydration()

Ön koşul: hydration, SSR’nin istemci tarafındaki tamamlayıcısıdır; tek başına açılan bir anahtar değildir. provideClientHydration() yalnızca zaten sunucuda veya önceden oluşturulmuş bir rotada işe yarar; RenderMode.Client rotasının kabuğunu sunucu HTML’sine çeviremez. Önce rota için SSR/önceden oluşturmayı etkinleştirin.

İki yeni yetenek SEO’ya komşu kullanıcı deneyimi açısından önemlidir; hiçbiri arama dizine eklemeyi değiştirmez:

  • Event replay (v18+): Hydration tamamlanmadan önce gerçekleşen desteklenen kullanıcı etkileşimlerini yakalar ve tamamlandıktan sonra yeniden oynatır. Desteklediği etkileşimlerde tıklama kaybını azaltır; bu bir UX/etkileşim özelliğidir, SEO özelliği değildir ve Google’ın neyi dizine eklediğini değiştirmez.
  • Artımlı hydration (v19 geliştirici ön izlemesi, v20’de kararlı): SSR, hydration, ertelenebilir görünümler ve event replay’in birlikte kullanılmasına bağlıdır; tek başına bir özellik değildir. @defer bloklarının hydrate triggers’ı, ilk oluşturma sırasında hangi sınırların hydration olmadan kalacağını belirler. hydrate never sınırı ilk yüklemede hydration olmadan kalır; ancak sonraki istemci oluşturma işlemlerinde (ör. rota değişiminden sonra) bağımlılıkların yüklenmesini zorunlu olarak engellemez. SEO etkisi dolaylıdır: başlangıçta daha az JavaScript hydrate etmek LCP’ye yardımcı olabilir, ancak tetikleyici yapılandırması tarayıcı zamanlaması değil oluşturma ayrıntısıdır.

Kritik tuzak: @if (isPlatformBrowser(...)) ifadesini doğrudan şablona koymak, sunucu ve istemcinin farklı işaretleme oluşturmasına — bir hydration uyuşmazlığına — ve bunun sonucunda düzen kayması ile CLS’ye yol açar. Şablonda platforma göre dallanmak yerine tarayıcıya özgü çalışma için afterNextRender() kullanın.

Başlık ve meta etiketleri — Angular’ın yerleşik servisleri

Angular <title> öğesinin metnine doğrudan bağlanamaz; bu nedenle head etiketlerini @angular/platform-browser içindeki iki servisle yönetin:

  • TitlesetTitle() / getTitle().
  • Metaname='description' veya property='og:title' gibi seçicilerle addTag(), addTags(), updateTag(), getTag(), removeTag().

Temel işler için üçüncü taraf kütüphaneye ihtiyacınız yoktur. Paylaşılan bir SEO servisi temiz bir kalıptır:

@Injectable({ providedIn: 'root' })
export class SeoService {
  private title = inject(Title);
  private meta = inject(Meta);

  updatePage(title: string, description: string) {
    this.title.setTitle(title);
    this.meta.updateTag({ name: 'description', content: description });
    this.meta.updateTag({ property: 'og:title', content: title });
  }
}

Başlıklar için yönlendiricinin TitleStrategy’si (Angular v14+) rota yapılandırmasında title ayarlamanıza ve gezinmede sayfa başlığını otomatik güncellemenize izin verir; bileşen başına kod gerekmez. document.title = ... ifadesini elle ayarlamayın; SSR altında doğru çalışması için Title servisini kullanın.

URL yapısı

  • Varsayılan HTML5 History API yönlendirmesini kullanın (PathLocationStrategy) — /products/shoes gibi temiz URL’ler elde edersiniz. Bunun için index.html dosyasında <base href="/"> bulunmalıdır.
  • Kamuya açık içerikte HashLocationStrategy / useHash: true kullanmayın. # işaretinden sonraki parça tanımlayıcıları HTTP isteğinden önce çıkarılır; dolayısıyla sunucu bunları hiç görmez ve Googlebot #/products yolunu güvenilir biçimde çözümleyemez. Tüm siteniz tek bir URL’ye indirgenebilir.
  • Tembel yüklenen rotalar dâhil, gezinme için gerçek <a href> bağlantıları kullanın. Tembel yükleme performans açısından uygundur; ancak bu rotalara giden bağlantılar tıklama işleyicileri değil, taranabilir bağlantılar olmalıdır.

Yapılandırılmış veri (JSON-LD)

Google, JSON-LD’nin JavaScript ile eklenmesini destekler. Sağlam Angular kalıbı; global document nesnesine doğrudan erişmek yerine Angular’ın DOCUMENT enjeksiyon belirtecini kullanarak bir <script type="application/ld+json"> öğesi oluşturan ve bunu document.head içine ekleyen bir servistir. Global erişim sunucuda çalışmaz. Tüm şemayı tek bir yerde tutun; statik HTML ile oluşturulmuş DOM arasında bölmeyin ve Zengin Sonuçlar Testi ile URL Inspection kullanarak doğrulayın.

Dinamik oluşturma — eski bir geçici çözüm, plan değil

Dinamik oluşturma, botlara Puppeteer, Rendertron veya prerender.io aracılığıyla önceden oluşturulmuş bir sürüm; kullanıcılara ise tam SPA sunar. Google, “dynamic rendering is a workaround and not a long-term solution,” (Türkçe çeviri) “dinamik oluşturma geçici bir çözümdür; uzun vadeli bir çözüm değildir,” ifadesini açıkça kullanır ve “better solutions than dynamic rendering” (Türkçe çeviri) “dinamik oluşturmadan daha iyi çözümler” bulunduğunu belirtir — bunlar sunucu taraflı oluşturma, statik oluşturma veya hydration’dır. Büyük ölçüde benzer içerik sunduğunuz sürece bu yaklaşım otomatik olarak cloaking sayılmaz; ancak ek bir oluşturma sunucusu gerektirir, içerik sapması riski yaratır ve gerçek kullanıcıların Core Web Vitals değerlerine hiçbir katkı sağlamaz. Yeni bir Angular uygulamasında bunun yerine @angular/ssr veya önceden oluşturmayı tercih edin.

Yaygın Angular SEO hataları

  1. Hash yönlendirmesi (# URL’leri) — tüm site tek bir URL gibi görünür.
  2. Title/Meta çağrılarının olmaması — her sayfa aynı başlık ve açıklamayı paylaşır.
  3. SSR/önceden oluşturmanın olmaması — içerik yalnızca ertelenmiş oluşturma dalgasından sonra mevcut olur.
  4. robots.txt içinde .js/.css dosyalarını engellemek — Google sayfayı oluşturamaz ve boş bir kabuğu dizine ekler.
  5. Bulunamadı görünümünde 200 döndürmek — soft 404 oluşturur; gerçek bir 404 döndürün veya noindex ekleyin.
  6. Title servisi yerine document.title = ... kullanmak.
  7. Şablondaki @if içinde isPlatformBrowser() kullanmak — hydration uyuşmazlığı → CLS.
  8. Sunucuda çalışan kodda window/localStorage/document nesnelerine erişmek — SSR çöker.
  9. Şemayı ham HTML ile oluşturulmuş DOM arasında bölmek.
  10. URL Inspection yerine yerel geliştirme ortamında test etmek — Googlebot’a değil varsayımlara güvenmek.

Angular SEO’yu test etme

  • URL Inspection (Search Console) doğruluk kaynağıdır: Taranan sayfa görünümü, Googlebot JavaScript’i çalıştırdıktan sonraki ve dizine eklenen oluşturulmuş HTML’yi gösterir; ayrıca JS konsol iletilerini ve engellenen kaynakları sunar. İsteğe bağlı bir oluşturma işlemi için Canlı Test çalıştırın.
  • JavaScript öncesindeki ham HTML’yi görmek için URL’yi curl ile çekin — boş bir kabuk, SSR kullanılmayan CSR anlamına gelir.
  • Zengin Sonuçlar Testi yapılandırılmış veriyi doğrular.
  • Ahrefs Site Audit (JS oluşturma açık) ve Screaming Frog (JS modu), ham DOM ile oluşturulmuş DOM arasındaki farkları büyük ölçekte karşılaştırır.
  • Lighthouse / PageSpeed Insights, oluşturma tercihinizin Core Web Vitals üzerindeki etkisini ölçer.

Angular SEO için kötü değildir; yalnızca farklıdır. Yanıta gerçek HTML koyun, head etiketlerini yönetin, URL’leri ve bağlantıları taranabilir tutun ve neyin oluşturulduğuna Google’ın araçlarının karar vermesine izin verin. Bu konu JavaScript SEO ve bu kümedeki headless CMS oluşturma sorularıyla yan yana durur; hepsindeki temel ders aynıdır: oluşturma modu neredeyse her şeyi belirler.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.