Next.js is the most SEO-friendly React framework available —but it's not automatic. The framework gives you the tools; you have to use them correctly.
This guide covers every SEO-relevant feature of Next.js 16, from the Metadata API to structured data, internationalization, Core Web Vitals, and beyond.
Why Next.js wins at SEO
Unlike client-rendered React apps (Create React App, Vite SPAs), Next.js renders HTML on the server by default. This means:
- Googlebot sees fully rendered HTML on every request —no JavaScript execution required
- Core Web Vitals are naturally better thanks to server rendering, optimized images, and efficient code splitting
- Metadata is available in the initial HTML —critical for Google Discover and AI crawlers
- Performance is built in —automatic image optimization, font optimization, and bundling
SSR vs SSG: which is better for SEO?
| Rendering strategy | Best for | SEO impact | |-------------------|----------|------------| | SSR (Dynamic) | Pages that change frequently (news, listings) | Good —HTML on every request, slightly slower TTFB | | SSG (Static) | Pages that change rarely (blog posts, about, landing) | Excellent —pre-built HTML served instantly | | ISR (Incremental) | Balance of freshness and speed | Excellent —static speed with periodic revalidation | | RSC (React Server Components) | All pages in the App Router | Excellent —zero client JS for server content |
App Router vs Pages Router for SEO (2026)
Next.js 16's App Router is now the recommended approach. For SEO, it offers:
- Simpler metadata API —export a
generateMetadatafunction from any page - Built-in layout nesting —automatic title prefixing and metadata inheritance
- Better image optimization —native lazy loading, priority hints, and responsive images
- Streaming and Suspense —faster Time to First Byte (TTFB)
The Next.js Metadata API
Every page needs a generateMetadata export. Here is the minimum viable implementation:
import type { Metadata } from "next";
export async function generateMetadata(): Promise<Metadata> {
return {
title: "Page Title | Site Name",
description: "Compelling description with target keywords, 150-160 characters.",
alternates: { canonical: "https://yoursite.com/page" },
openGraph: {
title: "Page Title | Site Name",
description: "Compelling description.",
url: "https://yoursite.com/page",
siteName: "Your Site",
images: [{ url: "https://yoursite.com/og-image.png", width: 1200, height: 630 }],
type: "website",
},
twitter: { card: "summary_large_image" },
robots: { index: true, follow: true },
};
}
Metadata inheritance through layouts
Next.js 16 merges metadata from layouts and pages. This is powerful for SEO:
- Root layout sets global defaults (site name, default OG image, robots)
- Nested layouts override specific fields (path, locale alternates)
- Pages set page-specific fields (title, description, canonical)
Structured data in Next.js
JSON-LD structured data is essential for rich results and AI citations. In Next.js, inject it directly in your page components:
export default function Page() {
const jsonLd = {
"@context": "https://schema.org",
"@type": "Article",
headline: "Your Article Title",
datePublished: "2026-07-23",
author: { "@type": "Organization", name: "Your Company" },
};
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
<article>{/* your content */}</article>
</>
);
}
Critical schema types for Next.js sites
- Organization —brand identity for Google Knowledge Panel
- Article —blog posts and news (required for Google News and Discover)
- BreadcrumbList —navigation context for rich results
- FAQPage —highest-impact schema for AI citations
- Product —e-commerce product pages
- LocalBusiness —physical location SEO
- Service —professional service pages
Core Web Vitals in Next.js
Next.js gives you the tools to hit all three CWV thresholds without extra work —but only if you avoid common pitfalls.
LCP (Largest Contentful Paint) —target < 2.5s
Next.js features that help:
next/imagewith automatic WebP/AVIF conversion, lazy loading, and sizing- Font optimization —Google Fonts self-hosted with
next/font, zero layout shift - Script optimization —
next/scriptwithstrategy="afterInteractive"or"lazyOnload" - Server components —zero client JS for content that doesn't need interactivity
Common LCP killers in Next.js:
- Client components that delay the main paint
- Unoptimized hero images without
priorityand explicitsizes - Third-party scripts blocking the main thread
INP (Interaction to Next Paint) —target < 200ms
- Minimize client component boundaries
- Use
useMemoanduseCallbackon expensive re-renders - Avoid large bundle imports —use dynamic imports with
next/dynamic - Defer non-critical JavaScript below the fold
CLS (Cumulative Layout Shift) —target < 0.1
- Always set explicit dimensions on
next/image - Reserve space for ads and embeds
- Use
next/font—fonts loaded via CSS@font-facecan cause layout shift - Avoid late-loading content that pushes existing content down
Internationalization (i18n) and hreflang
Multi-language sites must implement hreflang correctly. Next.js 16 with next-intl handles this well:
// app/[locale]/page.tsx
export async function generateMetadata({ params }) {
const { locale } = await params;
return {
alternates: {
canonical: locale === "en" ? "/en/page" : "/page",
languages: {
es: "/page",
en: "/en/page",
"x-default": "/page",
},
},
};
}
Common i18n SEO mistakes
- Missing
x-defaulthreflang tag - Inconsistent hreflang between sitemap and page tags
- Same content served under different URLs without canonical
- Translated pages that only exist in one language (Google sees them as incomplete)
Sitemap generation
Next.js 16 has a built-in sitemap API. Generate dynamic sitemaps for static and dynamic routes:
// app/sitemap.ts
export default async function sitemap() {
const posts = await getPosts();
const postUrls = posts.map((post) => ({
url: `https://yoursite.com/blog/${post.slug}`,
lastModified: post.updated,
changeFrequency: "monthly" as const,
priority: 0.6,
}));
return [
{ url: "https://yoursite.com", changeFrequency: "weekly", priority: 1 },
{ url: "https://yoursite.com/blog", changeFrequency: "weekly", priority: 0.7 },
...postUrls,
];
}
Image optimization for SEO and performance
Images are often 60-70% of a page's weight. Next.js's next/image handles most optimization automatically:
- WebP/AVIF conversion —serves modern formats automatically
- Responsive images —generates multiple sizes based on
sizesattribute - Lazy loading —images below the fold load only when needed
- Priority hints —use
priorityon LCP images for instant loading - Blur placeholder —prevents layout shift with a blurred preview
AI search optimization (GEO) with Next.js
Next.js sites have an advantage for AI visibility because they serve clean, structured HTML. Maximize it:
- Serve metadata in initial HTML —never inject canonical or meta tags via JavaScript
- Use FAQPage schema on pages with Q&A content
- Create llms.txt —Next.js can serve it as a static route:
app/llms.txt/route.ts - Keep content server-rendered —avoid client-only content that AI crawlers cannot parse
- Optimize for answer extraction —short paragraphs, clear headings, self-contained sections
Measuring SEO success on Next.js
Track these metrics after implementing Next.js SEO:
- Lighthouse scores —target 95+ on all four categories
- Core Web Vitals in CrUX —real user data from the Chrome User Experience Report
- Indexed pages in Google Search Console —should match your sitemap
- Organic traffic and keyword rankings —via Google Search Console or third-party tools
- AI citation rate —check ChatGPT and Perplexity for brand mentions
Need a Next.js site that ranks on its own? Check our custom web development service or let's talk.
