~3 min read • Updated Nov 1, 2025
1. Static Metadata with metadata
If your page metadata is static and doesn’t rely on runtime data, you can define it directly in layout.tsx or page.tsx:
export const metadata: Metadata = {
title: 'Home Page',
description: 'A brief description of this page',
}Next.js will automatically render this metadata in the <head> of your page.
2. Dynamic Metadata with generateMetadata
If your metadata depends on route parameters, external APIs, or parent metadata, use the generateMetadata function:
export async function generateMetadata({ params }, parent) {
const product = await fetch(`https://example.com/api/products/${params.id}`).then(res => res.json())
const previousImages = (await parent).openGraph?.images || []
return {
title: product.title,
openGraph: {
images: ['/product-image.jpg', ...previousImages],
},
}
}3. Good to Know
- You can only export either
metadataorgenerateMetadatafrom a route segment — not both generateMetadatais only supported in Server Components- fetch calls inside
generateMetadataare automatically memoized - If your metadata doesn’t rely on runtime data, prefer using the static
metadataobject
4. Supported Metadata Fields
- title: Page title
- description: Meta description for search engines
- openGraph: Social sharing metadata
- twitter: Twitter Card settings
- robots: Indexing rules
- icons: Favicon and Apple Touch icons
- manifest: Path to manifest.json
- verification: Site verification for Google, Yahoo, Yandex
- appLinks: Deep linking for mobile apps
- alternates: Canonical URLs, language variants, RSS feeds
5. Using metadataBase
To define a base URL for relative metadata fields like Open Graph images or canonical links:
export const metadata: Metadata = {
metadataBase: new URL('https://example.com'),
openGraph: {
images: '/og-image.png', // becomes https://example.com/og-image.png
},
}6. Combined Example
export const metadata: Metadata = {
title: {
default: 'My Shop',
template: '%s | My Shop',
},
description: 'Best products at the best prices',
openGraph: {
title: 'My Shop',
description: 'Shop online with high quality',
url: 'https://example.com',
siteName: 'My Shop',
images: [
{
url: 'https://example.com/og.png',
width: 1200,
height: 630,
},
],
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: 'My Shop',
description: 'Shop online with high quality',
creator: '@myshop',
images: ['https://example.com/og.png'],
},
}Summary
- Use
metadatafor static metadata - Use
generateMetadatafor dynamic metadata based on route or external data - Metadata is automatically injected into
<head>— no need fornext/head - Use
metadataBaseto simplify absolute URLs
Written & researched by Dr. Shahin Siami