Metadata and SEO

The App Router has a built-in metadata API. Export a static metadata object from any page.tsx to set the title, description, open graph tags, and social previews. Or export a generateMetadata function to compute them dynamically from the route params and data.

app/books/[id]/page.tsx
tsx
import { Metadata } from 'next';

interface PageProps {
  params: { id: string };
}

export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
  const res = await fetch('http://localhost:3000/api/books/' + params.id);
  const book = await res.json();
  return {
    title: book.title + ' | Bookstore',
    description: 'Read ' + book.title + ' by ' + book.author,
    openGraph: {
      title: book.title,
      description: 'by ' + book.author,
      images: book.coverUrl ? [{ url: book.coverUrl }] : undefined,
    },
  };
}

export default async function BookPage({ params }: PageProps) {
  // ... page content
}

Compute metadata per book so each page has its own title and description.

Because the page is server-rendered, these tags are in the HTML when Google or Twitter or Slack fetches the URL. No JavaScript needed, no workarounds. This is the SEO story that pure client-side React apps had to fight for, and Next.js gives it to you for free.

Quiz: Quiz

Loading practice…

Checkpoint: Server rendering checkpoint

Loading practice…