React vs Next.js for SEO: What Changes When the Server Renders
React and Next.js are not rivals in the usual sense: Next.js is a framework built on React. The SEO question is really about where your HTML is produced, in the visitor's browser or before it leaves the server, and what that does to crawling, indexing and speed.
Which one for SEO?
A plain React app rendered in the browser can be indexed by Google, but it asks Google to run JavaScript before it sees your content, and many other crawlers and link previews never run it at all. Next.js can send finished HTML from the server or from a build step, so content, titles and links are there on the first request. For public pages that need to rank, that is the safer default; for logged-in dashboards, plain React is fine.
How does Google handle a client-side React app?
Google describes its process in JavaScript SEO basics: it handles JavaScript apps in three phases, crawling, rendering and indexing. A page that needs JavaScript to show its content waits in a render queue first. Google says a page may stay in that queue for a few seconds, "but it can take longer than that". Only after rendering does Google see the text and links your React code puts on screen.
A typical client-rendered React build (the kind Create React App or a bare Vite setup produces) sends an almost empty HTML shell: a <div id="root"> and a script tag. Everything a crawler cares about, the headings, body copy, internal links and often the <title>, only exists after the script runs. Google can usually cope. The risks are elsewhere:
- Other crawlers. Google's own guide notes that not all bots can run JavaScript. Social previews, some search engines and many AI crawlers read the raw HTML only.
- Links that are not links. Google only discovers links that are
<a>elements with anhref. Buttons with click handlers that call a router are invisible to it. - Routing by fragments. Google asks single-page apps to use the History API and not
#/fragments, because it cannot reliably extract fragment URLs. - Soft 404s. A client-side router often returns HTTP 200 for a page that shows "not found". Google recommends a JavaScript redirect to a URL that really returns 404, or adding a
noindexrobots tag on error views. - Slow first paint. The browser must download, parse and run the bundle before anything useful appears, which tends to hurt Largest Contentful Paint on phones.
What does Next.js change?
Next.js lets each route decide where its HTML comes from. The choices that matter for SEO:
| Rendering mode | When the HTML is built | Good for |
|---|---|---|
| Static (prerendered) | At build time, once | Marketing pages, blog posts, documentation |
| Static with revalidation | At build time, then refreshed in the background on a schedule or on demand | Catalogues, listings, pages that change daily |
| Dynamic (server-rendered) | On each request | Search results, personalised or fast-changing pages |
| Client components | In the browser, after the server HTML arrives | Interactive widgets inside an otherwise rendered page |
The React team now points the same way. When it deprecated Create React App for new projects in February 2025, it recommended starting new apps with a framework such as Next.js or React Router, and noted that server rendering can improve SEO while also cutting the JavaScript a user must download before seeing content.
Metadata, sitemaps and robots in Next.js
The App Router gives you a static metadata export and a generateMetadata function for titles, descriptions, canonical URLs and Open Graph tags, documented in Metadata and OG images. One detail is easy to miss: on dynamically rendered pages Next.js can stream metadata after the page starts rendering. It disables that streaming for bots that expect metadata in the <head>, such as Bingbot and Twitterbot, and prerendered pages resolve metadata at build time, so static routes are the simplest case.
A sitemap.ts file in the app folder returns an array of URLs and Next.js serves it as /sitemap.xml. For big catalogues, generateSitemaps splits the list into several files, since Google allows 50,000 URLs per sitemap (see the sitemap reference).
// app/sitemap.ts
import type { MetadataRoute } from 'next'
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const posts = await getPublishedPosts() // your data source
return posts.map(p => ({ url: `https://example.com/blog/${p.slug}/`, lastModified: p.updatedAt }))
}
Is plain React ever the right choice for SEO?
Yes, when the page does not need to rank. Admin panels, customer portals, internal tools and anything behind a login gain nothing from server rendering and are simpler as a client-side app. A common and sensible split is a statically rendered marketing site and blog for search, with the product itself as a React app on a subdomain or under /app/, blocked from indexing.
If you must keep a client-rendered React site public, you can reduce the risk: prerender the key routes at build time, make every navigation item a real <a href>, set titles and canonicals per route, return true 404 status codes, and test the rendered HTML with the URL Inspection tool in Search Console rather than trusting what your browser shows.
Checklist before you launch either one
- View the raw HTML. Fetch the page with
curlor "view source". The main heading, body text and links should be there without JavaScript. - Check every route's head. Each URL needs its own title, description and self-referencing canonical, not one shared by the whole app.
- Test a missing URL.
/this-does-not-existshould return HTTP 404, not 200 with a friendly message. - Measure on a phone. Field data for Largest Contentful Paint, Interaction to Next Paint and layout shift tells you whether the bundle is too heavy.
- Inspect in Search Console. URL Inspection shows the HTML Google rendered and any resources it could not load.
Questions about React, Next.js and SEO
Is React bad for SEO?
No. React itself is fine. The risk comes from rendering all content in the browser, which makes crawlers run JavaScript before they see anything. React rendered on the server or at build time, for example through Next.js, gives crawlers finished HTML.
Can Google index a client-side rendered React app?
Usually, yes. Google crawls, queues the page for rendering, runs the JavaScript and then indexes what it sees. Rendering can be delayed, and other crawlers and link previews often do not run JavaScript, so key public pages are safer served as HTML.
Is Next.js automatically good for SEO?
No framework is. Next.js makes server and static rendering easy, but you still need unique titles and canonicals per route, real links, correct 404 status codes, a sitemap and fast pages. A badly configured Next.js site can rank worse than a careful React one.
Should I move my React site to Next.js?
If public pages that should rank are rendered only in the browser and are not being indexed or are slow on phones, moving them to Next.js is a reasonable fix. If the React app sits behind a login, there is little SEO reason to move it.
Not sure what Google sees on your React site?
Tell us one URL that should rank and does not. On a free call we compare its raw HTML with what Google renders, check its titles, links and status codes, and say plainly whether a Next.js move is worth it for you.