Next.js has become the default framework for production web apps, and the App Router — stable since Next.js 13.4 — makes it one of the best platforms for technical SEO. The primitives are in the right places: metadata lives in server components, OG images generate from JSX, sitemaps and robots files are typed conventions, and streaming with Suspense helps Core Web Vitals almost by default.
But "Next.js handles SEO" is also one of the most repeated half-truths in the ecosystem. The App Router gives you the tools. It doesn't wire them up for you. Misconfigured metadataBase means every canonical URL in your site points to localhost. Missing generateStaticParams means your dynamic pages get crawler-unfriendly 404s during build. A 'use client' boundary in the wrong place ships 200kb of JS that tanks your INP score.
This guide covers every layer of Next.js SEO, with production-ready patterns for each.
Why the App Router Changes the SEO Picture
The Pages Router gave you next/head — a component you dropped into any page to inject tags into <head>. It worked, but it had problems. Tags could be overridden inconsistently. There was no type safety. Canonical URLs were strings you had to build yourself. There was no native OG image story.
The App Router replaces next/head with the Metadata API: a typed, composable system where each layout.tsx and page.tsx exports either a static metadata object or a generateMetadata async function. Next.js merges these down the layout tree, with inner layouts and pages overriding outer ones. The result is predictable, colocated, and type-safe.
What this means in practice:
title.templatein your root layout propagates to every page automatically — no wrapper components needed.metadataBasesets the base URL once, and every relative URL in your metadata becomes absolute.metadata.alternates.canonicalhandles canonical tags without a separate component.metadata.openGraphandmetadata.twittergenerate all the social meta tags from one object.- The
opengraph-image.tsxfile convention generates OG images from JSX usingnext/og— per-page, at build time.
For Pages Router projects: you can still use next/head and it still works. But the Metadata API is not available in the Pages Router. Migration to the App Router is the path to the full feature set.
The Six Areas a Next.js Developer Needs to Get Right
1. The Metadata API
Every page needs title, description, canonical URL, and Open Graph tags. The App Router Metadata API handles all of these through a single typed export. The critical things to get right: metadataBase (without it, relative URLs break), title.template (for consistent titling across the site), and generateMetadata for dynamic pages where title and description come from a database or CMS.
The full production pattern — including typed generateMetadata, metadataBase, title.template, and robots — is covered in Next.js App Router Metadata API: The Complete SEO Setup.
2. Dynamic OG Images
Open Graph images are the thumbnail that appears when someone shares your URL on Slack, Twitter, or LinkedIn. Generic images get ignored. Relevant, per-page images get clicks.
next/og generates these images from JSX using Satori under the hood — your component renders to a PNG at build time (or on-demand). The file convention is opengraph-image.tsx colocated with your page.tsx. You get full access to the route segment's data, so you can generate images with the actual post title, author, and date.
The patterns for fonts, external data, and static-versus-runtime tradeoffs are in Next.js Dynamic OG Images with ImageResponse.
3. Sitemap and Robots
Search engines need to know what pages exist and which ones they're allowed to crawl. The App Router gives you app/sitemap.ts and app/robots.ts as file conventions — each exports a typed function that Next.js serves at /sitemap.xml and /robots.txt respectively.
The sitemap convention supports dynamic entries: you can query your database at build time and return an array of URL objects, each with lastModified, changeFrequency, and priority. For large sites, you can split into multiple sitemaps with a sitemap index.
The full production pattern is in Next.js Sitemap and Robots.txt with the App Router.
4. Canonical URLs
Canonical tags tell Google which URL is the "official" version of a page — critical for avoiding duplicate content penalties from pagination, query string variations, or HTTP/HTTPS/www inconsistencies.
In the App Router, canonicals go through metadata.alternates.canonical. Paired with metadataBase, you can use relative URLs everywhere and Next.js makes them absolute. The tricky part is dynamic pages — you need to set the canonical in generateMetadata using the route params.
Edge cases (trailing slashes, hreflang, multi-locale sites) are covered in Next.js Canonical URLs: The metadata.alternates Pattern.
5. Structured Data (JSON-LD)
The Metadata API doesn't cover structured data. JSON-LD lives in a <script type="application/ld+json"> tag in the page head, and you have to put it there yourself. The right pattern is a server component that renders a <Script> tag with dangerouslySetInnerHTML — this keeps the JSON-LD out of client bundles and gives you full TypeScript type safety over your schema objects.
The schema-dts package provides TypeScript types for every schema.org type. Combined with a small helper function, you get type-safe JSON-LD generation for Article, FAQ, BreadcrumbList, and any other schema you need.
The full pattern is in Next.js Structured Data: The Type-Safe JSON-LD Pattern.
6. Core Web Vitals
Next.js gives you a strong CWV baseline: next/image handles responsive sizes and WebP conversion automatically, Server Components reduce client JavaScript significantly, next/font eliminates layout shift from font swaps, and streaming with Suspense improves perceived performance on slow connections.
The gaps are where developers trip up: 'use client' boundaries that ship large third-party libraries, event handlers that block the main thread and kill INP scores, and hero images that are technically "above the fold" in the source but below the fold in the viewport on mobile.
The full optimization workflow — including the specific gotchas and how to diagnose them — is in Next.js Core Web Vitals: Native Optimizations and Where They Fall Short.
App Router vs. Pages Router: The SEO Differences
If you're maintaining a Pages Router project or migrating incrementally, here's what changes:
| Capability | Pages Router | App Router |
|---|---|---|
| Meta tags | next/head component | metadata export / generateMetadata |
| OG images | Manual <meta> tags, external service | opengraph-image.tsx convention, next/og |
| Sitemap | Manual API route or next-sitemap package | app/sitemap.ts built-in convention |
| Robots.txt | Static file in /public or API route | app/robots.ts built-in convention |
| Canonical URLs | Manual <link rel="canonical"> in next/head | metadata.alternates.canonical |
| JSON-LD | <Script> in next/head | <Script> in Server Component |
| Title templates | Manual string interpolation | title.template in root layout |
| Metadata inheritance | No inheritance — each page manages its own | Layout tree inheritance with override |
The Pages Router is not going away. Next.js continues to support it. But for new projects, the App Router is unambiguously the right choice for SEO — the metadata API alone eliminates a category of bugs that were common in Pages Router apps.
The Incremental Migration Path
If you have an existing Pages Router app and want the App Router's SEO capabilities, Next.js supports running both routers in parallel. You can adopt App Router pages incrementally:
- Start with
app/layout.tsxand move your root metadata there (replacing the_document.tsx<Head>tags). - Migrate your highest-traffic pages first — these benefit most from the improved metadata and OG image story.
- Add
app/sitemap.tsandapp/robots.ts— these work even if the rest of your app is still in the Pages Router. - Migrate remaining pages when it makes sense.
The incremental approach lets you ship SEO improvements without a big-bang rewrite.
Auditing Your Next.js Site with RankCrab
RankCrab is built on Next.js — so when we say the patterns in this cluster are production-ready, we mean we run them ourselves.
The 80-check audit catches the issues that slip through even when you think you've handled everything: missing metadataBase that corrupts canonical URLs, OG images that exceed Twitter's file size limit, structured data with required fields missing, and pages where noindex accidentally leaked from a staging environment.
The rank tracker tells you whether the SEO work is moving the needle. Technical correctness is necessary but not sufficient — you need to know which keywords are responding.
If you're starting a new Next.js project or auditing an existing one, run it through RankCrab before you ship. The metadata issues especially tend to be invisible until you share a URL and see a broken preview card.
What's Covered in This Cluster
- Next.js App Router Metadata API: The Complete SEO Setup — the production pattern for title, description, canonical, Open Graph, and robots via the Metadata API.
- Next.js Dynamic OG Images with ImageResponse — per-page social cards using
next/ogand theopengraph-image.tsxconvention. - Next.js Sitemap and Robots.txt with the App Router — typed
sitemap.tsandrobots.tsconventions, including dynamic entries from a database. - Next.js Canonical URLs: The metadata.alternates Pattern — canonical tags,
metadataBase, trailing slashes, and hreflang. - Next.js Structured Data: The Type-Safe JSON-LD Pattern — type-safe JSON-LD from server components using
schema-dts. - Next.js Core Web Vitals: Native Optimizations and Where They Fall Short — what Next.js handles automatically and where you still need to tune.