Platforms · Next.js
We built our own site on Next.js. Most SEO agencies haven't. When you're shipping React for performance, your SEO partner should ship React too.
SEO for Next.js sites — App Router and Pages Router. We work with engineering teams shipping React-based marketing sites, web applications, and content platforms. Server-rendered schema, programmatic SEO at scale, Core Web Vitals optimization, and AI engine citation done in code, not in dashboards.
Next.js at a glance
- Typical buyer
- SaaS, B2B tech, developer-focused brands
- Rendering modes
- SSR, SSG, ISR, RSC
- SEO foundation
- Excellent — when used correctly
- Our own stack
- Yes — this site is Next.js 16
The problem
Next.js gives you SEO superpowers and confuses most agencies into ignoring them.
Next.js produces some of the fastest, most SEO-friendly sites on the modern web — when used correctly. Server-rendered content, near-instant TTFB on edge runtimes, granular metadata APIs, programmatic routes for SEO at scale, and clean structured data via React components. Most SEO agencies don't understand any of it. They treat Next.js like a black box and add WordPress-shaped recommendations that don't apply. The teams winning Next.js SEO in 2026 work with partners who can read the code, ship the schema components, and review the PRs alongside their engineering team.
Platform-specific gotchas
The Next.js traps we fix on every engagement
These are the issues we find on most Next.js sites — including ones that previously hired SEO agencies. If your site has these, fixing them is usually the highest-leverage technical work available.
Client components hiding content from crawlers
The problem
React Server Components ship rendered HTML to the client. Client components render in the browser. AI crawlers (and sometimes Googlebot) don't always execute the JavaScript, so any 'use client' content that loads dynamically becomes invisible.
The fix
Server-render content that matters for SEO. Use client components only for interactivity (forms, animations, dropdowns). Static content, headings, body copy, and critical CTAs should be server components. Verify with View Source — if your H1 isn't in the initial HTML, it's likely invisible to crawlers.
Bad: SEO-critical content in a client component
'use client';
import { useState, useEffect } from 'react';
export default function ProductPage({ slug }: { slug: string }) {
const [product, setProduct] = useState(null);
useEffect(() => {
fetch(`/api/products/${slug}`).then(r => r.json()).then(setProduct);
}, [slug]);
if (!product) return <div>Loading...</div>;
// ❌ This H1 isn't in the initial HTML — crawlers may miss it
return <h1>{product.name}</h1>;
}Metadata API misconfiguration
The problem
Next.js's metadata API (App Router) is powerful but easy to misuse. Common mistakes: forgetting metadataBase, generating wrong canonical URLs, using static metadata where dynamic is needed, and missing OG image sizing.
The fix
Set metadataBase in the root layout. Use generateMetadata() for any page where title/description varies. Always include canonical, OpenGraph (with absolute image URL), and Twitter card. Validate with the Twitter Card Validator and Facebook Sharing Debugger after deploy.
app/layout.tsx — proper metadata base setup
import type { Metadata } from 'next';
export const metadata: Metadata = {
metadataBase: new URL('https://theseospot.com'),
title: {
default: 'SEOSpot — SEO + Link Building',
template: '%s | SEOSpot',
},
description: 'SEO and link building for B2B, SaaS, and ecommerce brands.',
openGraph: {
type: 'website',
siteName: 'SEOSpot',
images: ['/og-default.png'], // resolved against metadataBase
},
twitter: { card: 'summary_large_image' },
};Schema as React components vs raw JSON-LD
The problem
Some Next.js sites build schema as React components that interpolate badly, especially when content includes quotes, line breaks, or special characters. The schema renders but Google parses it as invalid.
The fix
Generate schema as plain JSON objects in TypeScript, then render via a single JsonLd component using dangerouslySetInnerHTML with JSON.stringify. This avoids React's JSX escaping issues and produces valid JSON-LD every time.
components/JsonLd.tsx — clean schema rendering
interface JsonLdProps {
data: object | object[];
}
export function JsonLd({ data }: JsonLdProps) {
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
/>
);
}
// Usage in a page:
// <JsonLd data={articleSchema({ headline, datePublished, ... })} />Sitemap and robots.txt not generated correctly
The problem
Hand-built sitemaps go stale immediately. Static robots.txt files don't differentiate between environments. Next.js teams often skip both because they're 'one more thing.'
The fix
Use Next.js's built-in sitemap.ts and robots.ts conventions. Generate sitemap programmatically from your content registries (services, blog posts, etc.). Generate robots dynamically based on environment so production allows crawling and preview/staging blocks it.
Edge runtime breaking schema injection
The problem
Some Next.js apps run on the Edge Runtime for performance. Edge runtime has Web API restrictions that can break certain server-side schema generation patterns, especially anything using Node.js modules.
The fix
Keep schema generation in pure JS/TS using Web APIs only. If you need Node-specific functionality, opt those routes back to the Node runtime. Most schema generation works fine on Edge if you avoid Node-only libraries.
Image optimization not configured
The problem
Teams use raw <img> tags or misconfigure next/image. Result: huge unoptimized images, no responsive srcset, no lazy loading, terrible LCP scores. Or worse — images optimized through next/image but with priority={false} on hero images, causing slow LCP.
The fix
Use next/image for every image. Set priority on above-the-fold hero images. Configure remotePatterns in next.config for any external image domains. Pre-define image sizes and use responsive sizes prop. Audit LCP after launch.
Proper next/image usage for above-the-fold images
import Image from 'next/image';
export default function Hero() {
return (
<section>
<h1>Headline</h1>
<Image
src="/hero.jpg"
alt="Descriptive alt text"
width={1920}
height={1080}
priority // ✓ critical for LCP on hero images
sizes="100vw"
quality={85}
/>
</section>
);
}ISR revalidation timing wrong for SEO
The problem
Incremental Static Regeneration is powerful but teams often set revalidate too short (every minute) or too long (once a day for daily-updating content). Either extreme creates SEO friction — too short wastes resources; too long serves stale content.
The fix
Match revalidate windows to actual content update frequency. Marketing pages: revalidate weekly or use on-demand revalidation. Blog: daily or on-demand. E-commerce products: hourly or on-demand. Use revalidateTag() or revalidatePath() on actual content changes rather than time-based intervals.
Next.js tools we use (and avoid)
Our opinionated Next.js stack
We're skeptical of agencies that recommend whatever's affiliate-friendly. Here's what we actually install on Next.js engagements — and what we tell clients to remove.
Next.js built-in metadata + sitemap + robots APIs
We recommendNative metadata, sitemap generation, and robots.txt — no plugins needed.
Use these fully. The metadata API is more flexible than any WordPress SEO plugin. Sitemap and robots conventions integrate with the build. Zero dependencies, zero overhead.
next-seo (npm package)
Use with careHigher-level SEO component library for Next.js — popular for Pages Router.
Useful on Pages Router projects where the metadata API doesn't exist. For App Router, the native metadata API is better. Don't add this to an App Router project — it's redundant.
@vercel/analytics + Speed Insights
We recommendReal-user performance monitoring including Core Web Vitals.
Lightweight, integrates natively with Vercel deployments. Useful for monitoring INP, LCP, CLS over time. Lazy-loads automatically.
Schema.org type packages (schema-dts)
We recommendTypeScript types for schema.org JSON-LD.
Helpful for catching schema errors at build time. We use it in our own schema generators for type safety.
Schema implementation
Structured data done correctly on Next.js
Schema is one of the highest-leverage technical investments for AI engine citation. Here's how we implement each type on Next.js.
Organization (root layout)
schema.org/Organization (root layout)Why it matters
Brand entity signals on every page for Knowledge Graph and AI citation.
How we implement it
Generate once in app/layout.tsx, inject via JsonLd component. Uses TypeScript helpers for type safety.
// lib/schema.ts
export function organizationSchema() {
return {
'@context': 'https://schema.org',
'@type': 'Organization',
name: 'SEOSpot',
url: 'https://theseospot.com',
logo: 'https://theseospot.com/logo.png',
sameAs: [
'https://twitter.com/seospot',
'https://linkedin.com/company/seospot',
],
};
}
// app/layout.tsx
import { JsonLd } from '@/components/JsonLd';
import { organizationSchema } from '@/lib/schema';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<JsonLd data={organizationSchema()} />
{children}
</body>
</html>
);
}Article (dynamic route)
schema.org/Article (dynamic route)Why it matters
Blog post and content article rich results, AI engine citation.
How we implement it
Generate per-page in generateMetadata or directly in the page component. Pull dates and author from the content source (MDX frontmatter, CMS API, etc.).
BreadcrumbList
schema.org/BreadcrumbListWhy it matters
Breadcrumb rich results.
How we implement it
Build a helper that takes the route path and generates BreadcrumbList from a nav config. Render once per page via JsonLd.
Service / Product (programmatic SEO)
schema.org/Service / Product (programmatic SEO)Why it matters
Service or product pages at scale with consistent schema.
How we implement it
Generate from a TypeScript registry file. The same registry that drives the route generation also feeds the schema, ensuring perfect alignment.
Combined @graph
schema.org/Combined @graphWhy it matters
Multiple schemas on one page, grouped for cleaner output.
How we implement it
Helper that takes multiple schema objects and combines them under a single @graph property. Renders as one JSON-LD script.
What you get
Deliverables on a Next.js engagement
Next.js technical audit
Rendering strategy (SSR/SSG/ISR/RSC), metadata config, schema generation, image handling, and Core Web Vitals reviewed.
Schema generator library
TypeScript module with generators for every schema type your site needs. Type-safe, testable, reusable across routes.
Metadata + sitemap + robots setup
Full metadata API configuration, programmatic sitemap.ts, environment-aware robots.ts.
Programmatic SEO build
Dynamic routes for comparison pages, integration pages, or content at scale — driven by your data layer.
Core Web Vitals optimization
next/image configuration, font loading, lazy loading strategy, third-party script handling.
Code review partnership
Ongoing PR reviews with your engineering team — we review SEO-affecting changes before they ship.
Services that fit next.js sites
The mix we usually recommend
SEO
SaaS SEO Services | Pipeline & Trial Growth
Most Next.js sites are B2B SaaS marketing sites or product platforms. Bottom-funnel work fits.
SEO
Technical SEO Services | Core Web Vitals & Schema
Next.js SEO is mostly technical SEO — schema in code, rendering optimization, performance work.
SEO
AI SEO Services | ChatGPT & Perplexity Citations
Next.js sites have the cleanest server-rendered HTML — ideal for AI engine citation.
Link building
Founder-Led Link Building | Podcasts & Expert Quotes
Technical founders building on Next.js usually have authority worth activating.
Industries that typically use Next.js
Common Next.js buyer profiles
Common questions
About Next.js SEO
Do you actually know Next.js, or are you a generalist agency?
Will you work with our engineering team or hand them PDF recommendations?
Can you do programmatic SEO on Next.js?
Do you handle App Router and Pages Router both?
What about headless CMS on Next.js — Contentful, Sanity, MDX?
What's your refund policy for Next.js engagements?
Send me your Next.js site. I'll tell you honestly what's broken.
A 45-minute call where I look at your Next.js site live and tell you what I'd prioritize. If we're a fit, we'll talk about working together. If not, I'll point you to who I'd hire instead.
Free · 45 min · No obligation