React SEO: what React's own docs now recommend, and the rendering, metadata and routing fixes that get a React site indexed
Why a client-only React app is hard for search, how to pick a rendering mode per route, and how to set titles, canonicals, links and 404s the way React and Google document them.
Published by AI Knows Us · Updated 21 October 2026
React SEO comes down to one thing: the pages you want found should reach crawlers as finished HTML, with the title, description, canonical link, main content and real links already in the server response. A client-only React app sends an almost empty page and relies on the crawler to run JavaScript, which Google does but many bots do not. React's own documentation now recommends starting with a framework such as Next.js or React Router, which can render each route on the server or at build time. Add titles and meta tags with React's built-in <title> and <meta> components or your framework's metadata API, route with the History API and normal <a href> links, and make missing pages return a real 404.
The details below come from react.dev, the Next.js documentation and Google Search Central's JavaScript SEO guides, all read on 22 October 2026. For how Google crawls, renders and indexes JavaScript in general, and how to test a page, see our JavaScript SEO guide. This page is about the React-specific choices.
Why a plain React app is hard for search
A React app built only for the browser ships an HTML file with an empty container and a script bundle. The content appears after the script runs. Google's documentation says Google Search runs JavaScript "with an evergreen version of Chromium," so Google can see the content after rendering. The same guide adds that server-side rendering or pre-rendering "is still a great idea because it makes your website faster for users and crawlers, and not all bots can run JavaScript."
Google has also stepped back from the old fix. Dynamic rendering, which served a pre-rendered copy to bots and the normal app to people, is described in Google's docs as "a workaround and not a long-term solution." Google recommends server-side rendering, static rendering or hydration instead.
What React itself now recommends
On 14 February 2025 the React team deprecated Create React App for new apps. Its post says Create React App "currently has no active maintainers" and points existing apps to a framework, or to a build tool such as Vite, Parcel or Rsbuild.
The react.dev page "Creating a React App" says: "If you want to build a new app or website with React, we recommend starting with a framework." It lists Next.js (App Router), React Router, and Expo for native apps, with TanStack Start and RedwoodSDK as up-and-coming options. Two points from that page matter for SEO:
- All the recommended frameworks support client-side rendering, single-page apps and static-site generation, and can be deployed to a CDN or static host without a server.
- They let you add server-side rendering route by route, "when it makes sense for your use case," without rewriting the app.
The react.dev guide to building a React app from scratch is direct about the trade-off: if you skip a framework and want server-side rendering, static site generation or React Server Components, "you will have to implement those on your own."
Choose a rendering mode for each kind of route
You do not need the same answer for every page. Decide per route.
| Route | Rendering that suits it | Why |
|---|---|---|
| Home, product, service, blog and docs pages | Static generation at build time | Complete HTML, fast to serve, changes on each release |
| Catalogue, listings, prices and stock | Server-side rendering | Fresh HTML on every request |
| Search results and filtered views | Server-side rendering, usually kept out of the index | Real HTML for users, without thousands of thin pages in Google |
| Dashboard, account and settings screens | Client-side rendering | Behind a login and not meant to rank |
If you build your own setup, React provides the pieces. The react-dom/static APIs, such as prerender and prerenderToNodeStream, render a React tree to static HTML. React's docs note that "a framework may call them for you" and most components never import them directly.
Titles and meta tags in React
Each page needs its own title and description. Google's guide says "unique, descriptive <title> elements and meta descriptions help users quickly identify the best result for their goal."
React's built-in components
React DOM now has built-in <title> and <meta> components. You render them from any component, and React "will always place the corresponding DOM element in the document head," wherever it sits in the tree. That lets each page component own its metadata:
export default function PricingPage() { return ( <> <title>Pricing | Example Co</title> <meta name="description" content="Plans and prices for Example Co." /> <h1>Pricing</h1> </> );
}
Two rules from the React docs prevent common bugs:
- Render only one title at a time. If two components render a
<title>, React puts both in the head, and the docs say the behaviour of browsers and search engines is then "undefined." - Pass the title a single string.
<title>Results page {pageNumber}</title>gives the component two children and causes an error. Use a template string:<title>{`Results page ${pageNumber}`}</title>.
On a client-only app, these tags still appear only after JavaScript runs. They are most useful when the page is rendered on the server or at build time, so the tags are in the first HTML response.
Next.js metadata
In the Next.js App Router, you export a static metadata object from a layout or page file, or a generateMetadata function when the title depends on data, such as a blog post fetched by its slug. Next.js then generates the head tags. Its docs note that both exports "are only supported in Server Components."
Canonical links
Google says the best place for the canonical link is the HTML. If you must set it with JavaScript, never change it to a different URL from the one in the original HTML. A React app that renders a default canonical in the HTML shell and swaps it on the client is giving Google two answers. Render the right canonical on the server, per route.
Routing and links
Google "can only discover your links if they are <a> HTML elements with an href attribute." Use your router's link component for navigation instead of onClick handlers on buttons or divs, and confirm in the rendered HTML that each link comes out as an anchor with a real href.
Use the History API for routes, not URL fragments. Google's example of bad practice is a single-page app that loads content from #/products and #/services. Googlebot cannot reliably resolve those as separate URLs. Clean paths such as /products and /services work.
Missing pages and soft 404s
In a client-routed app, a product that no longer exists often renders a "not found" message while the server returns status 200. Google calls this a soft 404. With server rendering, return a real 404 status from the route. In a client-only app, Google's docs give two options: redirect with JavaScript to a URL that returns 404 from the server, such as /not-found, or add a noindex robots meta tag to the error view.
If you have an existing Create React App
- List the routes that should rank: usually the home page, product or service pages, and content.
- Move to a framework from the react.dev list. Both Next.js and React Router support a client-only starting point, so you can migrate first and switch routes to server or static rendering one at a time.
- Start with the routes from step 1. Leave logged-in screens as they are.
- Move titles, descriptions and canonicals into the framework's metadata system or React's head components, rendered on the server.
- Check each converted route with JavaScript turned off. If the heading and copy are there, crawlers that do not render can read it too.
Questions about React SEO
Is React bad for SEO?
No. React renders well on the server and at build time. The problems come from client-only rendering, fragment routing and links that are not real anchors, and each has a direct fix.
Does Google index client-side rendered React?
Google renders JavaScript with an up-to-date Chromium, so it can. Google still recommends server or static rendering, because pages are faster and other bots do not all run JavaScript.
Do I still need React Helmet?
React DOM now places <title> and <meta> in the head on its own, and Next.js has its own metadata API. Many apps no longer need a separate head library. Check what your framework recommends before you add one.
Should I use Next.js for SEO?
Next.js is one of the frameworks react.dev recommends, alongside React Router and others. Any of them that renders your important routes as HTML on the server or at build time solves the core React SEO problem.
Is Create React App still supported?
It is deprecated for new apps since 14 February 2025 and continues in maintenance mode. The React team recommends a framework or a build tool such as Vite instead.
The readers that never run your bundle
Google renders JavaScript. Its own guide reminds you that not every bot does, and a reader that skips your bundle sees an empty container where your product description should be. Rendering on the server fixes that for search and for every other system that reads your pages. Whether an assistant like ChatGPT or Perplexity then names your product when someone asks for one is a separate reading, and AI Knows Us takes it.