Next.js for SEO: what it does better and what to watch

Next.js sends complete HTML, metadata and sitemaps by default, which suits search. Where it beats other setups, and five mistakes that still cost rankings.

By Sohail Hussain31 October 20266 min read

Next.js is good for SEO because it sends search engines complete HTML with the title, description, canonical URL and structured data already in place, and because its defaults (pre-rendered pages, optimised images, self-hosted fonts) make Core Web Vitals easy to pass. It does not rank a site on its own. A Next.js site can still be invisible to Google if content is rendered only in the browser, if status codes are wrong, or if the metadata is copied across every page.

This post covers what the framework does better than most setups, then the five mistakes we see on Next.js sites that cost them traffic.

What does Next.js do better for search than a typical site?

Four things, all on by default in the App Router.

Pages arrive as finished HTML. Layouts and pages are Server Components unless you opt out. They run on the server, at build time or on request, and the browser receives the full text of the page. Googlebot does not have to run JavaScript to see your headings, copy and links. Social media crawlers, which mostly do not run JavaScript at all, see the same thing.

Metadata is part of the code, per route. Each page exports a metadata object or a generateMetadata function. Next.js turns it into the <title>, meta description, canonical link, Open Graph and Twitter tags. Layouts set defaults and a title template, and pages override them. There is no plugin to configure and no way for two plugins to fight over the same tag. Setting up metadata and Open Graph is the step-by-step guide.

Sitemaps, robots.txt and share images are files in the app. A sitemap.ts file returns a list of URLs and Next.js serves valid XML at /sitemap.xml. A robots.ts file does the same for /robots.txt. An opengraph-image.tsx file draws a share image for every page from its title. Sitemaps and robots.txt in Next.js and generating Open Graph images show working versions.

Speed is the default, not a project. The next/image component serves resized, modern-format images and reserves their space so the layout does not jump. next/font self-hosts fonts with a size-matched fallback. Only Client Components ship JavaScript. These are the three things that usually decide whether a page passes Core Web Vitals, which Google uses as part of its page experience signals.

That combination is why it is the framework behind our website design and development work, and the longer argument is in why we build company websites with Next.js.

Next.js (App Router)WordPress with an SEO pluginSingle-page React app
HTML on first requestComplete, from the serverComplete, from PHPMostly empty until JavaScript runs
Titles and meta tagsMetadata API, per routePlugin settings, per pageAdded by a library in the browser
Sitemap and robots.txtCode in app/Generated by the pluginBuilt separately
Image optimisationBuilt inPlugin or host featureManual
Typical Core Web Vitals effortLowMedium; caching and plugin disciplineHigh

Which Next.js mistakes cost rankings?

Content that only exists after JavaScript runs

The most common problem is a page whose main content is fetched in the browser. A Client Component that loads products or blog posts inside useEffect sends Google a loading spinner. Google does render JavaScript, but it does so in a second pass, and other crawlers often never do. Fetch content in a Server Component and pass it down. Keep "use client" for the parts that need clicks, state or browser APIs. The server components explainer covers the split in plain terms.

A quick test: open the page, view the source (not the inspector), and search for a sentence from the body. If it is not there, crawlers may not see it either.

A 200 status on pages that should be 404s or redirects

Once a Next.js page starts streaming, its HTTP status is already sent. The Next.js docs are explicit about this: if notFound() runs after a <Suspense> boundary or loading.tsx has started the stream, the response stays 200 and Next.js adds a noindex tag instead. A redirect() called mid-stream becomes a client-side redirect rather than an HTTP one.

Google handles the noindex correctly, but a crawler may report these as soft 404s, and a client-side redirect is a weaker signal than a 301 or 308. Check for missing records before any await that sits under a Suspense boundary, and put permanent redirects in next.config.ts or in proxy.ts, which run before rendering. 301 vs 302 redirects covers the redirect side.

The same metadata on every page

A root layout with a title and description, and pages that never override them, gives every URL the same snippet. Google then rewrites the snippets or treats the pages as near-duplicates. Set a title.template in the root layout and a unique title and description in each page or in generateMetadata.

A related trap: metadata objects merge shallowly. If the layout sets openGraph with a site name and image, and a page sets openGraph with only a title, the page's object replaces the layout's completely. The site name and image disappear for that page.

Canonical URLs that are missing or relative to nothing

Without metadataBase in the root layout, relative URLs in canonical and Open Graph fields cause a build error, so most projects set it. The quieter problem is pages that never set alternates.canonical, so URLs with tracking parameters, trailing slashes or upper-case letters compete with the clean version. Set a canonical on every indexable page, and pick one trailing-slash style with the trailingSlash option so the other redirects.

Preview and staging URLs that get indexed

Every pull request on most Next.js hosts gets its own preview URL. Vercel adds a noindex header to preview deployments by default, but self-hosted staging servers and other platforms may not. If a staging site is public, protect it with a password or send X-Robots-Tag: noindex from it, and check Search Console for unexpected hostnames.

Does Next.js handle structured data?

Not through the Metadata API. JSON-LD is rendered as a <script type="application/ld+json"> tag inside the page or layout, which is the approach the Next.js JSON-LD guide recommends. It is a few lines of code per template: an Article object for posts, Organization on the homepage, BreadcrumbList where you show breadcrumbs, FAQPage where there is a real FAQ.

The guide also points out a security detail people miss: JSON.stringify does not escape <, so if any value comes from a CMS or user input, replace < with < before writing it into the page.

When does using Next.js for SEO not pay off?

When the content team needs to publish and restructure pages daily without a developer. Next.js with a headless CMS handles text, images and listings well, but adding a new page type or rearranging a template is code. If organic growth depends on a marketing team shipping new landing pages every week, WordPress or Webflow may get more pages live, and more pages written well usually matters more than a faster framework.

It also does not pay off as a fix for weak content. Moving a site to Next.js improves speed and crawlability. It does not improve the answers on the pages, and that is what ranks.

What should you check after launching a Next.js site?

  1. View source on three page types and confirm the main text, title, description and canonical are in the HTML.
  2. Fetch a URL that should not exist with curl -sI and confirm it returns 404, not 200.
  3. Open /sitemap.xml and /robots.txt and confirm they list production URLs only.
  4. Run a page through the meta tags generator to compare what you have with a complete head block.
  5. After four weeks, check Search Console's Pages and Core Web Vitals reports, and enter the field numbers in the Core Web Vitals checker.

The fuller list for any platform is our technical SEO checklist, and if you want someone to run it on your site, that is what our technical SEO work covers.

Was this guide useful?

Questions

Frequently asked.

Is Next.js better for SEO than WordPress?

Not by default in every case. Both can produce fast, crawlable pages with correct metadata. Next.js makes speed and clean HTML easier to get and keep, while WordPress makes editing and SEO plugins easier. A badly built site on either platform ranks badly.

Can Google index a Next.js site that uses client-side rendering?

Google renders JavaScript, so it usually can, but rendering is queued and other search engines and social previews may not run scripts at all. Content that matters for search should be in the server-rendered HTML, which is the default for Server Components.

Do I need a plugin for SEO in Next.js?

No. Titles, descriptions, canonical URLs, Open Graph tags, sitemaps and robots.txt are all built into the framework. You write them as code, so a developer sets them up once and the CMS supplies the values per page.

Sohail Hussain

Founder, MSH Technologies

Sohail has designed and built websites, web apps and AI products for over 12 years, for clients from Singapore-based industrial groups to early-stage SaaS startups. He writes about what actually worked.

Keep reading

Related guides.

All posts

Your next move

Like what you see? Tell us about it.

A process that takes too long, a website that undersells you, or an idea ready to take shape. Tell us where you are and we will suggest a useful next step.

India · Working with clients worldwide

We reply within a working day. No spam, ever.