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/head in App Router—use the Metadata API instead
  • Duplicating metadata in layout and page without understanding merge rules
  • Missing generateMetadata for 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