İçeriğe atla
Abdullah Üstün

7 Ağustos 2026 / 10 dk okuma / SEO

Next.js SEO Rehberi 2026: App Router ile Kurulum

Next.js App Router ile SEO kurulumu, Metadata API, sitemap.ts, JSON-LD, rendering stratejisi seçimi ve sık yapılan 7 hata tek rehberde bir arada.

İçindekiler

Next.js, React dünyasının en güçlü framework’ü. Ama 90+ projede gördüğümüz bir gerçek var: Next.js kullanmak tek başına SEO getirmiyor. Yanlış rendering stratejisi seçilmiş, metadata yarım bırakılmış bir Next.js sitesi, düzgün kurulmuş bir WordPress’ten daha kötü sıralanabiliyor.

İyi haber şu: App Router (Next.js 13+) ile SEO kurulumu hiç olmadığı kadar sistematik. Metadata API, sitemap.ts, robots.ts ve server component’ler doğru kullanıldığında ortaya crawler’ların bayıldığı bir site çıkıyor.

Bu rehberde 2026 itibarıyla eksiksiz bir Next.js SEO kurulumunu adım adım gösteriyoruz: rendering kararından JSON-LD’ye, Core Web Vitals’tan AI crawler uyumuna kadar.

Hızlı özet: Next.js SEO üç karara dayanır: doğru rendering stratejisi (mümkünse SSG/ISR), Metadata API ile eksiksiz title/description/OG ve sitemap.ts + robots.ts + JSON-LD üçlüsü. Client-side only render, çift H1 ve unutulan canonical en sık üç hatadır. AI crawler’lar JavaScript çalıştırmadığından sunucudan dönen HTML belirleyicidir.

Rendering Stratejisi: SEO’nun Yüzde 50’si Bu Kararda

Kural basit: içerik kullanıcıya göre değişmiyorsa statik üret. Next.js’te bir sayfanın SEO performansını en çok etkileyen şey, o sayfanın nasıl render edildiğidir. Metadata’dan da, schema’dan da önce gelir.

App Router’da elinizde dört seçenek var:

StratejiNasıl çalışırTTFBSEO etkisiNe zaman kullanın
SSG (statik)Build’de bir kez üretilirEn düşük (<100ms)Mükemmel: tam HTML, anında yanıtBlog, hizmet sayfası, landing
ISRStatik + revalidate ile arka planda yenilemeDüşükMükemmel: taze içerik + statik hızÜrün sayfası, haber, fiyat listesi
SSR (dynamic)Her istekte sunucuda renderOrta-yüksek (300-800ms)İyi ama TTFB riskiKişiye özel veya gerçek zamanlı içerik
CSR (client-only)Tarayıcıda JS ile renderKabuk hızlı, içerik geçZayıf: botlar boş sayfa görebilirDashboard, panel; asla halka açık içerik

Pratikte pazarlama sitelerinin %90’ı SSG + ISR karışımıyla çözülür. Bir e-ticaret ürün sayfasında export const revalidate = 3600 demek, saatte bir tazelenen ama her istekte statik hızda dönen bir sayfa demektir. SSR’ı ancak “bu içerik gerçekten her istekte farklı mı?” sorusuna evet diyebiliyorsanız seçin.

Kendi projelerimizde ölçtüğümüz fark net: aynı içeriğin SSR’dan SSG’ye alınması TTFB’yi tipik olarak 400-600ms’den 50-100ms bandına indiriyor. Bu doğrudan Core Web Vitals skorlarınıza yansıyor.

Metadata API: title, description ve OG Kurulumu

App Router’da <Head> bileşeni yok; onun yerine her layout.tsx ve page.tsx dosyasından metadata objesi veya generateMetadata fonksiyonu export edersiniz. Next.js bunları birleştirip <head> içine basar.

Kök layout’ta temel kurulum şöyle görünür:

// app/layout.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  metadataBase: new URL("https://siteniz.com"),
  title: {
    default: "Siteniz — Ana Değer Önermesi",
    template: "%s | Siteniz",
  },
  description: "140-155 karakterlik, tam cümle site açıklaması.",
  openGraph: {
    type: "website",
    locale: "tr_TR",
    siteName: "Siteniz",
  },
};

İki kritik detay:

  • metadataBase şart. Bunu tanımlamazsanız OG image ve canonical gibi göreli URL’ler yanlış üretilir; Next.js build’de uyarı basar ama site çalışmaya devam eder, hata sessizce canlıya gider.
  • title.template sayesinde alt sayfalar sadece kendi başlığını verir, marka eki otomatik eklenir. Çift marka eki (“Sayfa | Marka | Marka”) sorununu kökten çözer.

Dinamik sayfalarda ise generateMetadata kullanırsınız:

// app/blog/[slug]/page.tsx
export async function generateMetadata({ params }): Promise<Metadata> {
  const post = await getPost(params.slug);
  return {
    title: post.title, // 50-60 karakter hedefleyin
    description: post.excerpt, // 140-155 karakter, kesik olmasın
    alternates: { canonical: `/blog/${params.slug}/` },
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [{ url: post.ogImage, width: 1200, height: 630 }],
    },
  };
}

Burada alternates.canonical satırına dikkat edin. Next.js canonical’ı sizin yerinize yazmaz; unutulursa sayfa canonical’sız yayınlanır ve UTM’li, parametreli kopyalar Google’da ayrı URL olarak birikir. Denetlediğimiz Next.js sitelerinde en sık rastladığımız eksik bu.

generateStaticParams: Dinamik Sayfaları Statik Yapmak

generateStaticParams, dinamik route’ların ([slug]) hangi sayfalara açılacağını build zamanında söyler; böylece o sayfalar SSR yerine statik üretilir. SEO açısından bu, “dinamik URL yapısı + statik hız” demek: iki dünyanın en iyisi.

// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await getAllPosts();
  return posts.map((post) => ({ slug: post.slug }));
}

Bununla birlikte iki ayar daha önemli:

  • export const dynamicParams = false derseniz listede olmayan slug’lar 404 döner. Sonradan eklenen içerik için true bırakıp ISR ile birleştirmek genelde daha doğru.
  • 500+ sayfalık sitelerde hepsini build’de üretmek süreyi şişirir. En çok trafik alan sayfaları generateStaticParams’ta üretip kalanını ilk istekte ISR’a bırakmak dengeli bir çözüm.

sitemap.ts ve robots.ts: Kod Olarak Crawl Yönetimi

App Router’da sitemap ve robots birer TypeScript dosyasıdır; elle XML yazmazsınız. app/sitemap.ts build’de /sitemap.xml’e, app/robots.ts ise /robots.txt’ye dönüşür.

// app/sitemap.ts
import type { MetadataRoute } from "next";

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await getAllPosts();
  return [
    { url: "https://siteniz.com/", lastModified: new Date(), priority: 1 },
    ...posts.map((p) => ({
      url: `https://siteniz.com/blog/${p.slug}/`,
      lastModified: p.updatedAt,
    })),
  ];
}

lastModified alanını CMS’teki gerçek güncelleme tarihinden beslemek önemli; Google bu sinyali yeniden tarama önceliği için kullanıyor. Rastgele new Date() basmak “her şey bugün değişti” demek, sinyali çöpe çevirir.

// app/robots.ts
import type { MetadataRoute } from "next";

export default function robots(): MetadataRoute.Robots {
  return {
    rules: [
      { userAgent: "*", allow: "/", disallow: ["/api/", "/panel/"] },
      { userAgent: "GPTBot", allow: "/" },
      { userAgent: "PerplexityBot", allow: "/" },
    ],
    sitemap: "https://siteniz.com/sitemap.xml",
  };
}

Bir tuzak: bota özel bir grup açtığınızda o bot artık * grubundaki kuralları okumaz. GPTBot’a özel grup açıp disallow satırlarını tekrarlamazsanız, genel kısıtlarınız o bot için geçersiz kalır. Crawl kurgusunun tamamı için teknik SEO checklist’imize bakabilirsiniz.

JSON-LD: Schema’yı Server Component’te Basın

Next.js’te JSON-LD eklemenin tek doğru yolu, schema’yı sunucuda üretip ilk HTML’in içine gömmektir:

// app/blog/[slug]/page.tsx (server component)
export default async function Page({ params }) {
  const post = await getPost(params.slug);
  const jsonLd = {
    "@context": "https://schema.org",
    "@type": "Article",
    headline: post.title,
    datePublished: post.publishedAt,
    author: { "@type": "Person", name: "Abdullah Üstün" },
  };

  return (
    <article>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      {/* içerik */}
    </article>
  );
}

dangerouslySetInnerHTML burada gerçekten tehlikeli değil; veri sizin kontrolünüzde ve JSON.stringify’dan geçiyor. Asıl tehlikeli olan, schema’yı client component’te useEffect ile enjekte etmek: JavaScript çalıştırmayan botlar (AI crawler’ların tamamı dahil) o schema’yı hiç görmez. Hangi sayfa tipine hangi schema’nın uyduğunu schema markup rehberinde detaylandırdık.

next/image ile Core Web Vitals

next/image doğru kullanıldığında LCP ve CLS’in büyük kısmını kendiliğinden çözer: otomatik WebP/AVIF dönüşümü, boyut bazlı srcset, lazy loading ve layout shift önleme hepsi paket dahilinde.

SEO açısından üç kural yeter:

  1. Hero görseline priority verin. Ekranın üstündeki LCP görseli lazy load edilirse LCP kolayca 1 saniye uzar. priority prop’u preload ekler; hedefiniz LCP <1.5s olmalı.
  2. width/height (veya fill + oranlı kap) her zaman tanımlı olsun. CLS’in bir numaralı sebebi boyutsuz görseldir.
  3. sizes prop’unu gerçekçi yazın. Yazmazsanız tarayıcı masaüstünde de tam genişlik varsayar ve mobil kullanıcıya gereksiz büyük dosya iner.

Bir de alt metni: next/image alt’ı zorunlu tutar ama “resim1” yazan alt SEO’ya hiçbir şey katmaz. Görseli tarif eden tam bir cümle yazın.

Sık Yapılan 7 Next.js SEO Hatası

Denetlediğimiz Next.js projelerinde tekrar tekrar aynı hatalarla karşılaşıyoruz:

  1. Client-side only render. Sayfanın ana içeriği "use client" + fetch ile tarayıcıda çekiliyor. Googlebot render kuyruğuyla belki görür, AI botlar hiç görmez. İçerik server component’te kalmalı.
  2. Çift H1. Layout’ta logo H1, sayfada başlık H1. Her sayfada tek H1 olmalı; logoyu div veya p yapın.
  3. Canonical unutulmuş. alternates.canonical yazılmadığı için parametreli kopyalar indekse sızıyor.
  4. metadataBase tanımsız. OG image URL’leri localhost:3000 olarak canlıya çıkıyor. Evet, gerçekten görüyoruz bunu.
  5. 404 yerine 200 dönen soft-404. Bulunamayan slug’da notFound() çağırmak yerine “İçerik bulunamadı” yazısıyla 200 dönmek. Google bunları düşük kaliteli sayfa olarak biriktirir.
  6. loading.tsx yokken ağır SSR. Yavaş veri kaynağına bağlı SSR sayfası, streaming olmadan TTFB’yi 1s+ seviyeye taşır.
  7. Sitemap’te silinen sayfalar. CMS’ten silinen içerik sitemap’ten düşürülmüyor, Search Console 404 uyarılarıyla doluyor. sitemap.ts her build’de güncel listeyi çekmeli.

Bu yedi maddenin ortak teması şu: Next.js size güçlü araçlar veriyor ama hiçbirini sizin yerinize açmıyor.

AI Crawler’lar Neden Next.js Çıktısını Önemsiyor?

2026 itibarıyla GPTBot, ClaudeBot ve PerplexityBot JavaScript çalıştırmıyor; sunucunuzun döndürdüğü ilk HTML neyse, AI’ın gördüğü site odur. ChatGPT’nin veya Perplexity’nin sizi kaynak gösterip göstermeyeceği, büyük ölçüde bu ilk yanıtta belirleniyor.

Bu, rendering kararını daha da kritik hale getiriyor:

  • SSG/ISR sayfalar AI botlar için ideal: tam içerikli HTML, düşük TTFB, timeout riski yok.
  • SSR sayfalar çalışır ama yavaş veri kaynağında bot timeout’a düşebilir; AI crawler’lar klasik botlardan daha sabırsız.
  • CSR sayfalar AI için pratikte görünmezdir.

Kontrol yöntemi basit: terminalden curl https://siteniz.com/sayfa/ | grep "aradığınız metin" çalıştırın. Metin ham HTML’de varsa AI botlar okuyabiliyor demektir. Yoksa o içerik yalnızca JavaScript sonrası oluşuyor ve AI görünürlüğünüz sıfıra yakın.

Bir adım ötesi, siteye llms.txt eklemek ve alıntılanabilir içerik yapısı kurmak; bu konunun tamamını GEO tarafında ayrıca ele alıyoruz. AI botların sitenize gerçekten erişip erişemediğini de varsaymayın: robots.txt “Allow” dese bile WAF katmanı botu 403/429 ile çevirebiliyor, sunucu loglarından doğrulayın.

Kurulum Kontrol Listesi

Yayına çıkmadan önce hızlı bir tur:

  • Her halka açık sayfa SSG veya ISR ile üretiliyor
  • Kök layout’ta metadataBase + title.template tanımlı
  • Her sayfada benzersiz title (50-60 kr) ve description (140-155 kr)
  • alternates.canonical tüm indexlenebilir sayfalarda var
  • sitemap.ts gerçek lastModified ile dinamik üretiliyor
  • robots.ts’te AI botlar bilinçli şekilde yönetiliyor
  • JSON-LD server component’te, ilk HTML’in içinde
  • LCP görselinde priority, tüm görsellerde boyut + sizes
  • Tek H1, notFound() ile gerçek 404
  • curl testi: içerik ham HTML’de görünüyor

Bu listeyi geçen bir Next.js sitesi, hem Google’da hem AI arama yüzeylerinde teknik olarak hazırdır. Gerisi içerik kalitesi ve otorite meselesi.

Next.js Siteniz İçin Profesyonel Destek

Next.js projeniz var ama organik trafik beklediğiniz yerde değilse, sorun çoğu zaman bu rehberdeki maddelerin bir alt kümesidir; hangileri olduğunu ölçmeden bilemezsiniz. SEO hizmetimiz kapsamında Next.js sitelerine özel teknik denetim yapıyor, rendering stratejisinden metadata kurgusuna kadar tüm katmanları elden geçiriyoruz. Durumunuzu konuşmak için iletişim sayfasından ücretsiz 30 dakikalık görüşme planlayabilirsiniz.


Bu yazı 2026’da güncellendi. Next.js sürümleri ve crawler davranışları değiştikçe rehber güncelleniyor.

SSS

Sıkça sorulanlar

Next.js SEO için SSG mi SSR mı kullanmalıyım? +
İçerik her istekte değişmiyorsa SSG (statik üretim) her zaman ilk tercih olmalı: en hızlı TTFB, en ucuz sunucu maliyeti ve crawler'ların en sevdiği çıktı. İçerik saatlik/günlük değişiyorsa ISR ile revalidate süresi verin. SSR'ı yalnızca kullanıcıya özel veya gerçek zamanlı içerik için ayırın; her istekte render maliyeti hem TTFB'yi hem crawl bütçesini yer.
Next.js Metadata API ile canonical nasıl eklenir? +
generateMetadata içinde alternates.canonical alanını kullanırsınız. En temiz yöntem, kök layout'ta metadataBase tanımlayıp sayfa bazında göreli path vermek: metadataBase new URL('https://site.com') + alternates: { canonical: '/blog/yazi-slug/' }. Böylece her sayfa kendi mutlak canonical URL'ini üretir ve parametre/kopya URL sorunları biter.
Next.js'te JSON-LD schema en doğru nasıl eklenir? +
Server component içinde bir script etiketi ile: type='application/ld+json' verip içeriği JSON.stringify ile basarsınız. Veri sunucuda üretildiği için schema ilk HTML'de yer alır; Googlebot da AI crawler'lar da JavaScript beklemeden okur. Client component içinde useEffect ile schema enjekte etmek en sık yapılan hatadır çünkü JS çalıştırmayan botlar onu hiç görmez.
App Router'da sitemap ve robots.txt nasıl oluşturulur? +
Kod dosyası olarak: app/sitemap.ts bir MetadataRoute.Sitemap dizisi döner, app/robots.ts ise MetadataRoute.Robots objesi döner. İkisi de build sırasında /sitemap.xml ve /robots.txt olarak servis edilir. Dinamik içerikte sitemap.ts içinde CMS'ten slug listesini çekip lastModified değerleriyle birlikte dönmek, Google'ın güncel sayfaları hızlı keşfetmesini sağlar.
AI crawler'lar Next.js sitelerini okuyabiliyor mu? +
Sunucudan dönen HTML doluysa evet. GPTBot, ClaudeBot ve PerplexityBot 2026 itibarıyla JavaScript çalıştırmıyor; sayfanın içeriği client-side render'a bırakılmışsa bu botlar boş bir kabuk görüyor. SSG/ISR/SSR ile üretilen Next.js sayfaları ise sorunsuz okunur. Kontrol basit: curl ile sayfayı çekin, metin HTML kaynağında görünüyorsa AI botlar da görür.

Form

Bu konu hakkında konuşalım mı?

30 dakikalık ücretsiz görüşmeyle ihtiyacınızı netleştirelim.

Form gönderdiğinizde KVKK kapsamında size dönüş yapabilmemiz için iletişim bilgilerinizi kullanmamıza izin vermiş olursunuz.

Next.js SEO'nun 2026'daki temeli üç karardan geçer: doğru rendering stratejisi (mümkünse SSG veya ISR), Metadata API ile eksiksiz title/description/OG kurulumu ve sitemap.ts + robots.ts + JSON-LD üçlüsü. Client-side only render, çift H1 ve unutulan canonical, Next.js projelerinde en sık görülen üç SEO hatasıdır. AI crawler'lar JavaScript çalıştırmadığı için sunucudan dönen HTML kritik önemdedir.