Next.js cookbook · Beginner
Add SEO metadata, Open Graph and sitemaps
Give every page correct titles, descriptions, social previews and a sitemap for search engines.
Approach
Export static metadata in layouts and generateMetadata for dynamic pages (it can reuse cached data fetches). Add app/sitemap.ts and app/robots.ts, and opengraph-image.tsx for generated social images.
Solution
// app/layout.tsx
import type { Metadata } from "next";
export const metadata: Metadata = {
metadataBase: new URL("https://shop.example.com"),
title: { default: "Acme Shop", template: "%s · Acme Shop" },
description: "Quality gear for developers.",
};
// app/products/[slug]/page.tsx
export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
const product = await getProductBySlug((await params).slug); // deduplicated with the page's fetch
if (!product) return { title: "Not found" };
return {
title: product.name,
description: product.summary,
alternates: { canonical: `/products/${product.slug}` },
openGraph: { title: product.name, images: [{ url: product.imageUrl, width: 1200, height: 630 }] },
};
}
// app/sitemap.ts
import type { MetadataRoute } from "next";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const products = await listProductSlugs();
return [
{ url: "https://shop.example.com", changeFrequency: "daily", priority: 1 },
...products.map((p) => ({ url: `https://shop.example.com/products/${p.slug}`, lastModified: p.updatedAt })),
];
}
Pitfalls
- Duplicate titles across pages.
- Missing canonical URLs for filtered/paginated variants.
- Fetching the same data twice without caching (
cache()/ fetch dedupe).
Variations
- JSON-LD structured data via a
<script type="application/ld+json">in the page.
Further reading: Next.js: Metadata and OG images
Reference: https://nextjs.org/docs/app/getting-started/metadata-and-og-images
More Next.js recipes
- Add a Content Security Policy with nonces in Next.js
- Add dark mode to Next.js without a flash
- Avoid data-fetching waterfalls in Server Components
- Build a validated JSON API with Route Handlers
- Create encrypted session cookies in Next.js
- Handle errors and 404s in the App Router
- Handle forms with Server Actions and validation
- Keep secrets and server code out of the client bundle