Next.js exposes a Metadata API so Server Components can set <title>, descriptions, Open Graph tags, and robots rules without manually editing head in every page.
Static metadata
// app/about/page.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'About Us',
description: 'We build learning tools.',
};
export default function AboutPage() {
return <h1>About</h1>;
}
Dynamic metadata
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const post = await getPost((await params).slug);
return { title: post.title, description: post.excerpt };
}
SEO habits
- One meaningful
h1per page; heading hierarchy for accessibility - Canonical URLs for duplicate content
- Structured data (JSON-LD) for products and articles when needed
- Server-render critical content—avoid empty shells filled only by client fetch for public pages
Self-check
- Why is metadata usually defined in Server Components?
- When do you use
generateMetadatainstead of a static export?