Next.js\'de SEO
Next.js 15\'in Metadata API\'si, SSR sayesinde arama motorlarının görebileceği gerçek meta etiketler üretir. CSR uygulamalarındaki SEO sorunları yoktur.
Statik Metadata
// app/blog/page.tsx
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Blog | Ininia Teknoloji",
description: "Yazılım, teknoloji ve dijital dönüşüm hakkında güncel yazılar.",
keywords: ["next.js", "react", "typescript", "web geliştirme"],
openGraph: {
title: "Blog | Ininia Teknoloji",
description: "Yazılım ve teknoloji yazıları",
type: "website",
locale: "tr_TR",
images: [
{
url: "https://ininia.com/og-image.png",
width: 1200,
height: 630,
},
],
},
twitter: {
card: "summary_large_image",
title: "Blog | Ininia Teknoloji",
description: "Yazılım ve teknoloji yazıları",
},
};
export default function Blog() {
return <div>...</div>;
}
Dinamik Metadata (generateMetadata)
// app/blog/[slug]/page.tsx
import { Metadata } from "next";
interface Props {
params: Promise<{ slug: string }>;
}
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params;
const yazi = await yaziGetir(slug);
if (!yazi) {
return { title: "Yazı Bulunamadı" };
}
return {
title: `${yazi.baslik} | Blog`,
description: yazi.ozet,
openGraph: {
title: yazi.baslik,
description: yazi.ozet,
type: "article",
publishedTime: yazi.yayinTarihi,
images: [{ url: yazi.kapakGorseli }],
},
alternates: {
canonical: `https://sitem.com/blog/${slug}`,
},
};
}
export default async function BlogYazisi({ params }: Props) {
const { slug } = await params;
const yazi = await yaziGetir(slug);
return <article>...</article>;
}
Root Layout\'ta Varsayılan Metadata
// app/layout.tsx
export const metadata: Metadata = {
metadataBase: new URL("https://sitem.com"),
title: {
default: "Sitem",
template: "%s | Sitem", // Her sayfaya " | Sitem" eklenir
},
description: "Varsayılan açıklama",
robots: {
index: true,
follow: true,
},
};
Sitemap Oluşturma
// app/sitemap.ts
import { MetadataRoute } from "next";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const yazilar = await tumYazilariGetir();
return [
{ url: "https://sitem.com", lastModified: new Date() },
{ url: "https://sitem.com/hakkimizda", lastModified: new Date() },
...yazilar.map(yazi => ({
url: `https://sitem.com/blog/${yazi.slug}`,
lastModified: new Date(yazi.guncellenmeTarihi),
})),
];
}
Önemli Noktalar
- metadata export ile statik SEO meta etiketleri tanımlanır
- generateMetadata ile dinamik sayfalarda SEO verisi çekilir
- Root layout'ta metadataBase ve template tanımlanmalı
- app/sitemap.ts ile otomatik XML sitemap oluşturulur