Next.js Metadata
Set page titles, Open Graph tags, and SEO with the Metadata API
Overview
The Metadata API configures <head> elements for SEO and social sharing. Export a static metadata object or a dynamic generateMetadata function from layout.tsx or page.tsx.
Syntax / Usage
// Static metadata
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Stackademic',
description: 'Learn to code with structured paths',
openGraph: {
title: 'Stackademic',
description: 'Learn to code',
url: 'https://stackademic.com',
siteName: 'Stackademic',
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: 'Stackademic',
},
}
// Dynamic metadata
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>
}): Promise<Metadata> {
const { slug } = await params
const post = await getPost(slug)
return {
title: post.title,
description: post.excerpt,
}
}
Examples
Title template in root layout:
export const metadata: Metadata = {
title: {
default: 'Stackademic',
template: '%s | Stackademic',
},
}
// Child page title: "Learn Python | Stackademic"
Robots and canonical:
export const metadata: Metadata = {
robots: { index: true, follow: true },
alternates: { canonical: 'https://example.com/about' },
}
Common Mistakes
- Using
next/headin App Router—use the Metadata API instead - Duplicating metadata in layout and page without understanding merge rules
- Missing
generateMetadatafor dynamic OG images on shareable pages - Setting metadata in Client Components—it only works in Server Components
See Also
app-router routing server-components api-routes