Next.js 15 App Router & Server Components

Ders 4/5 25 dakika

SEO Optimisation with the Metadata API

Static and dynamic metadata, Open Graph, Twitter Cards, and auto-generated sitemaps with Next.js Metadata API.

SEO in Next.js

Next.js 15's Metadata API generates real server-rendered meta tags that search engines can read. No client-side SEO workarounds needed.

Static Metadata

// app/blog/page.tsx
import { Metadata } from "next";

export const metadata: Metadata = {
  title: "Blog | Ininia Technology",
  description: "Up-to-date articles on software, technology and digital transformation.",
  keywords: ["next.js", "react", "typescript", "web development"],
  openGraph: {
    title: "Blog | Ininia Technology",
    description: "Software and technology articles",
    type: "website",
    locale: "en_US",
    images: [{ url: "https://ininia.com/og-image.png", width: 1200, height: 630 }],
  },
  twitter: {
    card: "summary_large_image",
    title: "Blog | Ininia Technology",
  },
};

export default function Blog() {
  return <div>...</div>;
}

Dynamic Metadata with generateMetadata

// app/blog/[slug]/page.tsx
import { Metadata } from "next";

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);

  if (!post) return { title: "Post Not Found" };

  return {
    title: `${post.title} | Blog`,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      type: "article",
      publishedTime: post.publishedAt,
      images: [{ url: post.coverImage }],
    },
    alternates: {
      canonical: `https://mysite.com/blog/${slug}`,
    },
  };
}

Root Layout — Default Metadata

// app/layout.tsx
export const metadata: Metadata = {
  metadataBase: new URL("https://mysite.com"),
  title: {
    default: "My Site",
    template: "%s | My Site", // appends to every page
  },
  description: "Default description",
  robots: { index: true, follow: true },
};

Auto-Generated Sitemap

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

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const posts = await getAllPosts();

  return [
    { url: "https://mysite.com", lastModified: new Date() },
    { url: "https://mysite.com/about", lastModified: new Date() },
    ...posts.map(post => ({
      url: `https://mysite.com/blog/${post.slug}`,
      lastModified: new Date(post.updatedAt),
    })),
  ];
}

Önemli Noktalar

  • metadata export defines static SEO meta tags
  • generateMetadata fetches dynamic SEO data for dynamic pages
  • metadataBase and template should be set in root layout
  • app/sitemap.ts generates an XML sitemap automatically