CPCODELAB
Next.js

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