Metadata and SEO with generateMetadata
8 min read
Built-In SEO Support
Next.js manages <head> metadata through a typed Metadata object. For static metadata, export a metadata constant. For dynamic metadata that depends on route params or fetched data, export an async generateMetadata function.
tsx
// src/app/about/page.tsx — static metadata
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "About Us | CPCODELAB",
description: "Learn about the CPCODELAB team and our mission.",
openGraph: {
title: "About Us | CPCODELAB",
description: "Learn about the CPCODELAB team and our mission.",
type: "website",
},
};
export default function AboutPage() {
return <main><h1>About Us</h1></main>;
}tsx
// src/app/blog/[slug]/page.tsx — dynamic metadata
import type { Metadata } from "next";
type Props = { params: Promise<{ slug: string }> };
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params;
const post = await fetchPost(slug);
return {
title: `${post.title} | CPCODELAB Blog`,
description: post.excerpt,
};
}
export default async function Page({ params }: Props) {
const { slug } = await params;
const post = await fetchPost(slug);
return <article><h1>{post.title}</h1></article>;
}
async function fetchPost(slug: string) {
return { title: "My Post", excerpt: "An excerpt.", slug };
}Set a metadataBase URL in your root layout's metadata export so that relative OpenGraph image URLs resolve correctly in production.
Ready to test yourself?
Practice Next.js— quiz & coding exercises