Your React SPA isn’t ranking.
A hybrid partial port to Next.js. We migrate your public, SEO-critical routes to a Next.js app that sits in front of your existing SPA. Your authenticated product is untouched. Same domain. No rewrite.

You’re here because one of these is true.
All three share a root cause: crawlers see an empty <div id="app"> until JavaScript executes, and JS-rendered content is indexed late and unreliably.
We don’t rank.
Marketing pages, pricing, blog posts — they exist, but Google doesn’t show them. You’ve seen competitors with worse content outrank you and you can’t figure out why.
Search Console says we’re not indexed.
You’ve opened Google Search Console and seen the "Discovered – currently not indexed" verdict on page after page. You know client-side rendering is the problem. You don’t want to rewrite the whole app to fix it.
Our Core Web Vitals are terrible.
Pages load slowly, content jumps around as it renders, and interactions feel laggy. Google’s Core Web Vitals report is deep in the red. Performance work on a client-rendered SPA has diminishing returns.
The hybrid partial port.
You don’t want to throw away your SPA, and you shouldn’t have to. The minimum fix is to move the pages that need to rank — not the pages users log into.
Next.js sits in front of your public routes.
We build a Next.js app that server-renders your marketing pages, blog, pricing, and any other SEO-critical surface. Crawlers get fully-rendered HTML on the first response. No more waiting on JavaScript execution, no more empty-page indexing, no more ranking cliff.
dnsA reverse-proxy seam joins the two apps on one domain.
Path-based split at the edge: example.com and public routes go to Next.js; example.com/app/* (or your auth boundary) keeps routing to your existing SPA. Same domain, cookies survive the boundary, sessions unaffected.
Your authenticated app stays exactly as it is.
We don’t touch your product. No rewrites, no framework migration, no disruption to the team shipping features inside the app. The SPA keeps running; only the pages Google cares about move.
What’s included.
Every engagement breaks into two buckets: fixed setup work that happens once, and per-surface work that scales with the number of public templates being ported.
Setup
Fixed fee, once per project
- check_circleNext.js project bootstrap + Vercel deploy pipeline
- check_circleReverse-proxy seam (edge rewrites or DNS)
- check_circleAuth / cookie / session continuity across the seam
- check_circleAnalytics continuity (GA4, Plausible, or your stack)
- check_circleSEO baseline capture before cutover
- check_circlePassword-protected staging for pre-cutover QA
- check_circleCutover plan with rollback procedure
- check_circlePost-cutover monitoring: Google Search Console re-submission, sitemap, URL inspection, daily Indexing-report checks for 14 days
Per ported surface
One price per public route template
- check_circleServer-rendered Next.js page
- check_circleSEO meta: title, description, canonical
- check_circleOpen Graph and Twitter Card tags
- check_circleJSON-LD structured data where applicable
- check_circleSitemap entry and robots.txt coverage
- check_circlenext/image optimization for media
- check_circleData fetching wired to your existing backend
- check_circleVisual-parity QA against the SPA version
Post-cutover, you’re not on your own.
The migration isn’t finished at cutover. Three overlapping windows cover you through the period where SEO, ranking, and field performance data actually stabilize.
Defect window
Any defect against the acceptance criteria is fixed free for two weeks after cutover. Critical issues acknowledged within 1 business day.
Ranking-regression window
If we cause an indexing or ranking regression against the pre-cutover baseline, we fix it at no cost. Attribution is evidence-based, not blame-based.
Core Web Vitals window
Google’s real-user performance data takes 28 days per datapoint to stabilize. We stay on the hook for Core Web Vitals regressions attributable to our build for the full 70 days.
Pricing.
Engagements are quoted after a 30-minute diagnosis call. Quote = a fixed setup fee plus a per-surface price, multiplied by a complexity score we walk through with you on the call.
We don’t take projects under three surfaces. Below that, setup dominates and the math doesn’t work for either of us.
Book a 30-min diagnosis callarrow_forwardFrequently asked.
Do you rewrite my whole app?
expand_more
What counts as a "surface"?
expand_more
Do you work on Vue, Angular, or Nuxt apps?
expand_more
What if my API is slow?
expand_more
What happens if something breaks after launch?
expand_more
Book a 30-minute diagnosis call.
We’ll walk your public tree, skim the rendering surface, flag hard-gate blockers, and give you a quote range before the call ends. No slides, no sales script.
event_availableSchedule on Calendlyopen_in_new