Metadata & SEO
Declare titles, descriptions, Open Graph and Twitter cards. Generate dynamic metadata per page.
Every page and layout can export a metadata object or a generateMetadata function. Next.js merges metadata from the root layout down to the leaf page, then renders the right tags in <head>.
Static metadata
// app/layout.js
export const metadata = {
title: {
default: "Acme",
template: "%s · Acme",
},
description: "We sell calm software.",
openGraph: {
siteName: "Acme",
images: ["/og-default.png"],
},
};The template field is the slick part. Child pages set just their title, and Next.js wraps it: Pricing → Pricing · Acme.
Per-page metadata
// app/pricing/page.js
export const metadata = {
title: "Pricing",
description: "Simple plans for every team.",
};
export default function PricingPage() { /* ... */ }Dynamic metadata
When the title depends on data — a blog post, a product — export an async generateMetadata function. It receives params and searchParams (both Promises in Next.js 16).
// app/blog/[slug]/page.js
export async function generateMetadata({ params }) {
const { slug } = await params;
const post = await getPost(slug);
return {
title: post.title,
description: post.summary,
openGraph: {
images: [post.coverUrl],
},
};
}Generated images, sitemaps and robots
- **
opengraph-image.js** ortwitter-image.jsin a route folder render dynamic social cards using theImageResponseAPI. - **
sitemap.js** exports a function returning URLs — Next.js serves/sitemap.xml. - **
robots.js** exports a robots config — Next.js serves/robots.txt.
// app/sitemap.js
export default async function sitemap() {
const posts = await getAllPosts();
return [
{ url: "https://example.com/" },
...posts.map((p) => ({
url: `https://example.com/blog/${p.slug}`,
lastModified: p.updatedAt,
})),
];
}alternates: { canonical: '...' } on pages that have duplicates or filters. It's the smallest SEO win you can ship.Try it
Make this product page expose a dynamic title and description based on the loaded product.
Need a hint?
Export an async generateMetadata function that fetches the product and returns the title/description.
Quiz
Pick the best answer. You only get one shot per question.
1. Which export gives you a per-page title using a global suffix like `· Acme`?
2. How do you make metadata depend on the route's params (e.g., a post slug)?
3. Which special file generates a Next.js-served `/sitemap.xml`?