Next.js SEO: Rendering Strategies, Metadata API, and App Router Done Right

No Comments
Next. Js seo: rendering strategies, metadata api, and app router done right

Next.js gives you four rendering modes per route, and choosing the wrong one is the most common reason a React site indexes badly. This guide pairs each strategy with the App Router Metadata API so Googlebot receives fully-rendered HTML with correct <title>, canonical, and Open Graph tags on the first request, not after a second JavaScript pass.

Why rendering strategy is an SEO decision, not just a performance one

Googlebot crawls in two waves. It first reads the raw HTML response, then queues the page for rendering with a headless Chromium that executes JavaScript. If your critical content and metadata only appear after client-side hydration, you depend entirely on that second wave, which is deferred and never guaranteed for low-priority URLs. Server-rendered HTML removes that dependency: the content Google needs is present in the initial response.

The practical rule for Next.js: ship meaningful HTML and complete metadata from the server. The App Router does this by default because components are React Server Components unless you opt out with "use client". The decision left to you is when that HTML is generated, which is where SSG, ISR, and SSR diverge.

SSG, ISR, and SSR: pick by content freshness, not by habit

In the App Router you don't call getStaticProps or getServerSideProps anymore. The rendering mode is inferred from how you fetch data and from route segment config. Here is how to map each to a content type:

  • Static (SSG), HTML built once at deploy time. Best for content that rarely changes: marketing pages, documentation, glossary entries, completed blog posts. Fastest possible TTFB, cheapest to serve, trivially crawlable. A route is static by default when its fetches are cacheable and it uses no dynamic functions.
  • Incremental Static Regeneration (ISR), static HTML that is rebuilt in the background on a schedule. Best for large catalogs and content that updates periodically but not per-request: product pages, category listings, author archives. You get static-page crawlability with eventual freshness. Enable it with a revalidate window: export const revalidate = 3600 or per-fetch via fetch(url, { next: { revalidate: 3600 } }).
  • Server-rendered (SSR), HTML generated on every request. Reserve this for genuinely per-request content: personalized dashboards, search results, anything reading cookies or live pricing. SSR is fully crawlable too, but it costs the most and adds latency, so don't default to it. Opt in with export const dynamic = 'force-dynamic' or by reading request-time APIs like cookies() or headers().

For a typical content or commerce site the answer is overwhelmingly SSG or ISR. SSR should be the exception you can justify, not the baseline.

Generate static paths so your whole catalog gets built

For dynamic routes like app/blog/[slug]/page.tsx, export generateStaticParams to tell Next.js which pages to pre-render at build. This is what turns a dynamic segment into thousands of indexable static URLs:

  • Return the full set of params you want statically generated. Pair it with ISR revalidate so new entries regenerate without a full redeploy.
  • Control the fallback behavior with export const dynamicParams = true (render unknown slugs on-demand) or false (return a 404 for anything not in the list). For SEO, false is safer when your URL set is finite, because it prevents thin or junk URLs from rendering 200s.

The Metadata API: server-rendered tags, done once

The App Router replaces next/head and react-helmet entirely. You export metadata from a layout.tsx or page.tsx and Next.js injects the tags into the server response. There are two forms:

  • Static, export const metadata = { ... } for pages whose tags never change.
  • Dynamic, export async function generateMetadata({ params }) when title and description depend on fetched data. Fetch calls here are deduplicated against the same fetches in your page component, so you don't pay twice.

A solid generateMetadata for a content page covers title, description, canonical, Open Graph, and Twitter card:

  • Set title and description from your CMS data, with sensible fallbacks for null fields.
  • Set alternates: { canonical: '/blog/' + slug } to declare a single canonical URL and kill duplicate-parameter dilution.
  • Populate openGraph and twitter with an explicit images entry; Next.js will not invent a social image for you.

Two project-wide settings save you from common errors. Set metadataBase in your root layout (export const metadata = { metadataBase: new URL('https://example.com') }) so relative OG image and canonical URLs resolve to absolute ones. And use the title template object, title: { default: 'Brand', template: '%s | Brand' }, so child pages get consistent, non-truncated titles without repeating the brand by hand.

Sitemaps, robots, and structured data the native way

Next.js ships file conventions that produce valid, server-rendered SEO assets:

  • app/sitemap.ts exports a function returning your URL list with lastModified. Generate it from the same data source as your pages so it never drifts out of sync. For very large sites, return multiple sitemaps via generateSitemaps.
  • app/robots.ts exports rules and a sitemap reference. Avoid blanket Disallow patterns that accidentally hide rendered routes.
  • For JSON-LD, render a <script type="application/ld+json"> tag directly in your server component with the schema object stringified. Because the component is server-rendered, the structured data is in the initial HTML where Google reads it.

Common mistakes that quietly break crawlability

  1. Marking a page "use client" at the top level. This pushes rendering to the browser and forfeits server metadata for that subtree. Keep pages and layouts as Server Components; isolate interactivity into small client leaf components.
  2. Forcing dynamic rendering by accident. Calling cookies(), headers(), or searchParams in a page opts the entire route into SSR. If you only need a value for one widget, fetch it lower in the tree or move it to a client component so the route stays static.
  3. Forgetting metadataBase. Without it, Open Graph images and canonicals stay relative and fail validation in social and search tools.
  4. Letting dynamicParams default to true on an unbounded route. Bots and link-fuzzers can spin up infinite indexable URLs. Set it to false for finite URL sets.
  5. Over-aggressive revalidation. A revalidate of a few seconds on a high-traffic catalog effectively turns ISR into SSR under load. Match the window to how often content actually changes.

FAQ

Is SSR better for SEO than SSG? No. Both deliver fully-rendered HTML, so crawlability is equivalent. SSG is faster and cheaper, so prefer it; choose SSR only when content must be per-request.

Does ISR hurt indexing? No. Crawlers always receive a complete static page; regeneration happens in the background and is invisible to them.

Can I still use the Pages Router? Yes, and getStaticProps/getServerSideProps plus next/head remain valid. But the App Router's Metadata API and server-default rendering make correct SEO the path of least resistance, which is why new builds should start there.

Get this right and the pattern is simple: render on the server, generate statically wherever content allows, regenerate incrementally where it changes, and let the Metadata API emit complete tags in the first response. That combination is what makes Google render a React framework site cleanly on the first pass.

Want this handled properly on your site?

It is exactly the kind of work an advanced technical SEO audit covers. See how an advanced SEO audit works →

Claude Vincent is a technical SEO consultant focused on crawlability, rendering, and AI-search visibility. He writes the field guides and case studies at SEO ProCheck, with a bias toward the durable, unglamorous work that decides whether search engines and AI answer engines can actually read and cite a site.

    About SEO ProCheck

    Technical SEO consulting and GEO strategy with 20 years of enterprise experience. Case studies, resources, and tools for search and AI visibility.

    Work With Me

    Technical SEO audits, GEO strategy, site migrations, and international SEO. Hourly consulting for teams who need hands-on support, not just reports.

    Subscribe to our newsletter!

    More from our blog