All Articles
Engineering

Should You Migrate Your React SPA to Next.js for SEO?

O
Osama Habib
October 14, 2026 9 min read
Should You Migrate Your React SPA to Next.js for SEO?

Your React app might rank on Google and still be invisible to ChatGPT. Here's how to tell if your SPA is costing you traffic, when a Next.js migration is worth it, and cheaper fixes to try first.

Migrate your React single-page app (SPA) to Next.js only if the pages you need people to find (home, pricing, features, comparisons, docs and blog) are rendered in the browser and their content is missing from the raw HTML. If most of your product lives behind a login, keep the SPA and fix only the public pages. In 2026 the case is stronger than it used to be, because most AI crawlers read raw HTML and don't run JavaScript.

I rebuilt the frontend of Emergi Mentors, an Australian mentorship SaaS, in Next.js 14 with server-side rendering, and led the technical SEO overhaul that fixed its poor search indexing. This guide is the decision process I'd walk any founder or CTO through before committing engineering time to a migration.

Why Do React SPAs Struggle With Google and AI Search?

A classic React SPA (built with Create React App, Vite or many AI app builders) sends the browser an almost empty HTML page, usually a single div with an id of "root", plus a JavaScript bundle. Everything else arrives only after that JavaScript runs: your headings, product copy, pricing, page titles, meta descriptions, canonical tags, social preview tags and structured data.

For people with a modern browser, that's fine. For crawlers, it's a problem in three ways.

Google can render JavaScript, but rendering is a separate step after crawling. If a script fails, a resource is blocked, or content only appears after a click, Google can miss it. Per-page titles and descriptions set in JavaScript are also often wrong or duplicated across routes.

AI crawlers are the bigger issue now. In its December 2024 study of AI crawler traffic, Vercel found that the major AI crawlers (including OpenAI's and Anthropic's) download JavaScript files but don't execute them. So a page whose content only exists after JavaScript runs can look blank to the tools founders increasingly worry about, such as ChatGPT and Claude, even while it ranks on Google.

Social previews break for the same reason. When someone shares your pricing page on LinkedIn or Slack, the preview bot reads the raw HTML and often finds no title, description or image.

How Can You Tell If Your SPA Is Actually Costing You Traffic?

You can answer this in about five minutes, without reading any code:

  1. Open your pricing page, right-click and choose "View page source" (not "Inspect"). Search for a sentence of your pricing copy. If it isn't there, crawlers that don't run JavaScript can't see it either.

  2. In Google Search Console, use URL Inspection on the page and view the crawled page to see what Google actually rendered.

  3. Ask a developer to fetch the page with a plain HTTP request (for example curl) and check whether the content is in the response.

  4. Open a few different pages and check that each one has its own title and meta description in the page source.

  5. Ask ChatGPT or Perplexity a direct question about your product's pricing or features and see whether it can describe them.

Symptoms, Likely Causes, and Fixes

Symptom

Likely cause

Fix

Page source shows an empty root div

Content rendered only in the browser

Server-render or prerender public pages

Every page has the same title in search results

Metadata set in JavaScript after load

Per-route metadata in the HTML

Shared links show no preview image or text

Open Graph tags added by JavaScript

Put Open Graph tags in the initial HTML

Search Console shows "Discovered, currently not indexed" for key pages

Thin or empty initial HTML, weak internal links

Server-rendered content plus a proper sitemap

AI assistants can't describe your product

AI crawlers don't execute JavaScript

Make key content available in raw HTML

When Is Migrating to Next.js Worth It?

This is the core decision. Here's how I'd call it:

Your situation

My call

Public marketing pages are client-rendered, and organic or AI traffic matters to you

Migrate the public pages first

Your product is mostly behind a login, and the marketing site is separate

Keep the SPA; make sure the marketing site is server-rendered

You only have a handful of simple, static public pages

Prerender them instead of rewriting

You're still on Create React App

You need to move anyway (React officially sunset CRA in February 2025), so choose Next.js if search matters

You built with an AI app builder

Check what rendering your platform offers today before rewriting anything

The honest summary: if search and AI visibility drive your growth, client-side rendering on public pages is a real handicap, and fixing it is worth engineering time. If your growth comes from sales, partnerships or paid ads, and your marketing pages already render properly, a migration can wait.

What Are the Cheaper Alternatives to a Full Rewrite?

A full rewrite isn't the only option. Three cheaper paths are worth considering first.

Prerendering or Static Snapshots

A prerendering setup generates static HTML for your public routes so crawlers get full content. It works well for a small number of mostly static pages. Google describes dynamic rendering (serving crawlers a different, prerendered version) as a workaround rather than a long-term solution, so treat it as a bridge, not a destination.

A Separate Marketing Site

Many SaaS companies run the marketing site (home, pricing, features, blog) on a server-rendered framework and keep the product as an SPA on a subdomain such as app.yourdomain.com. It isolates the SEO problem cleanly. The trade-offs are two deployments to maintain, and some care with login sessions and cookies across the two.

An Incremental Migration

Next.js documents an incremental path for Create React App and Vite projects: you first run your existing SPA inside Next.js, then convert the routes that matter for search to server rendering one at a time. You don't stop shipping features for months, and you get the SEO benefit on the most important pages first.

What Does a Migration Actually Involve, and What Can Break?

A migration is an SEO project as much as a framework change. The checklist I'd use:

  • Inventory every public URL, and map any that change to their new URL with a 301 redirect.

  • Give every route its own title, meta description and canonical tag in the server-rendered HTML.

  • Generate the sitemap automatically, so new pages are never missed.

  • Put structured data (JSON-LD) in the initial HTML, not injected later.

  • Keep trailing-slash behaviour the same as before, or redirect consistently.

  • Keep interactive client components small, so the main content stays server-rendered.

  • Fix hydration errors (mismatches between server and browser output) before launch.

  • Re-check login, sessions and cookies, which often behave differently once pages render on the server.

  • Confirm analytics still records every page view.

On Emergi Mentors, the rebuild moved the frontend to Next.js 14, TypeScript and Tailwind CSS with server-side rendering, to cut initial load time and improve Core Web Vitals. The SEO overhaul that went with it covered three things together: server rendering, JSON-LD structured data and automated sitemaps. That combination is what fixed the indexing problems.

One point founders are often relieved to hear: the backend didn't need to change. Emergi's APIs are built in FastAPI, and they kept running behind the new Next.js frontend. A frontend migration is not a full product rewrite.

How Long Does a Migration Take, and Who Should Own It?

I won't give you a universal number, because the honest answer depends on a few things:

  • How many public routes need server rendering.

  • How your pages fetch data (and whether that data is available on the server).

  • How authentication works today.

  • How much content and metadata needs to be moved or rewritten.

If you want a sense of how engineering timelines are usually estimated, I've written about how long it takes to build a custom web app (https://osamahabib.com/blog/how-long-to-build-a-custom-web-app).

On ownership: this works best with one full stack engineer who understands both rendering and technical SEO. An SEO agency alone can tell you what's wrong but usually can't change how your app renders. A frontend developer focused only on UI may ship a beautiful new site that loses rankings because redirects or metadata were missed. You want one person accountable for both sides.

What I Learned Rebuilding a SaaS Frontend in Next.js

Three lessons stuck with me:

  1. Treat it as an SEO migration, not a framework swap. The framework is the easy part. Redirects, metadata, canonicals and sitemaps are where rankings are won or lost.

  2. Server rendering, structured data and sitemaps work as a set. Any one of them alone helps a little. Together they make every important page easy for search engines and AI tools to read and understand.

  3. Keep the API. Separating the frontend migration from the backend kept the scope manageable and the product stable.

This site follows the same approach: osamahabib.com is built with Next.js, renders its pages on the server, ships JSON-LD structured data, publishes an llms.txt file and explicitly allows AI crawlers. If you're comparing the two frameworks more generally, my Next.js vs React guide (https://osamahabib.com/blog/nextjs-vs-react-which-one-should-you-learn-in-2026) covers the differences.

Frequently Asked Questions

Can Google index a React single-page app?

Yes. Google crawls, renders and indexes JavaScript pages. But rendering is a separate step, so content that depends on blocked resources or user interaction can be missed, and per-page metadata set in JavaScript is often wrong.

Can ChatGPT see a client-side rendered website?

Often not. Vercel's 2024 study of AI crawler traffic found that the major AI crawlers download JavaScript files but don't execute them, so content that only appears after JavaScript runs is likely invisible to them. Content in the raw HTML is what they can read.

Do I have to rewrite my whole app to move to Next.js?

No. Next.js documents an incremental migration path from Create React App and Vite. Only your public pages need server rendering, and your backend API can stay exactly as it is.

Is prerendering enough instead of server-side rendering?

For a small, mostly static marketing site, often yes. For growing content such as a blog, docs or comparison pages, or when you need accurate metadata on many pages, server rendering or static generation is the more durable fix.

Will migrating to Next.js hurt my current rankings?

It can if URLs change without 301 redirects, if metadata or canonical tags are lost, or if trailing-slash behaviour changes. Inventory every URL first, and compare the raw HTML of key pages before and after launch.

Planning a Next.js Migration on Your Team?

If you're a founder or CTO planning this move and you're hiring a full stack engineer who has already done it on a live SaaS, I'd like to hear about the role. I'm open to full-time remote Full Stack Engineer roles. You can see the SaaS work behind this post (https://osamahabib.com/services/saas-development), download my CV (https://osamahabib.com/docs/Osama_Habib_CV.pdf), or get in touch here (https://osamahabib.com/contact).

O

Osama Habib

Multan, Pakistan

Full Stack Developer specialising in Next.js, Node.js, and the MERN stack. I write about modern web development, system design, and practical engineering.