About Stackra

Stackra is a free website audit tool for small and mid-sized businesses. Our own site is a React single-page app served by Express, around 42 marketing and blog routes in total. We hit this problem on our own site, which is why we have a story to tell about it.

Why we did not switch to Next.js or Remix

Server-side rendering frameworks like Next.js, Remix, and Nuxt solve the same problem by rendering HTML on a Node server for every request. They are the industry default answer. We considered them and decided against, for four reasons.

  • Our marketing pages are essentially static. The same HTML works for every visitor. SSR's main value, dynamic per-request HTML, did not apply to anything we needed crawlers to see.
  • Migrating to Next.js or Remix is a real architectural change: routing rewrite, data-fetching refactor, layout migration. Adding a build-time prerender step on top of our existing setup is additive, not architectural.
  • Static HTML on disk is the cheapest, fastest, most cacheable response a server can produce. SSR adds a render server we have to run, monitor, and pay for.
  • The pages on Stackra that genuinely need dynamism, like the report viewer and dashboard, are intentionally not indexable. They never needed SSR for SEO.

Effort and footprint, side by side

The honest cost comparison between migrating to SSR and the prerender setup we shipped. The prerender numbers are actuals from our codebase. The SSR numbers are a realistic estimate of migrating a Vite + React app of similar surface size.

SSR migration vs Stackra's prerender approach
DimensionSSR (Next.js / Remix)Prerender (what we shipped)
Initial dev timeWeeks1-2 days
Files changedHundreds across routing, layouts, data hooks3 in the core path; a handful more for validation and route centralization
Production infrastructureNode render server (often per region)Static files served by the existing Express layer
Per-request CPU costRender every requestZero. Send a file.
Build-time costStandard bundle build+30-60 seconds for the headless browser pass
Cache strategyEdge cache + revalidation rulesHTML on disk, no special cache layer
Failure modes you'll hitRender server outages, hydration mismatches, render-time memory leaksRoute-list drift, missing API stubs, headless browser quirks
ReversibilityHard. SSR changes data fetching everywhere.Easy. Delete the script and the static.ts check.

Effort estimates assume an existing Vite + React SPA of similar surface size to Stackra (around 42 indexable routes including the blog). Modern edge runtimes have lowered SSR's operational cost; the trade-off is real but smaller than it used to be.

How to know if this fits your site

Match the shape of your site to the rendering model. Use this as a starting point, not an absolute rule.

Platform / site-shape decision matrix
Site shapePrerenderSSRWhy
Marketing site (a few hundred routes)RecommendedOverkillSame HTML works for everyone. SSR's per-request value does not apply.
Blog with steady cadenceRecommendedNot neededDeploy-per-change cadence is fine. Static files are the cheapest response.
Documentation site, frequent updatesWorkableRecommendedHundreds of routes plus deploy-on-merge cadence stresses prerender build times.
E-commerce, hundreds of SKUsWorkableRecommendedEither works. SSR wins if inventory or pricing changes between deploys.
E-commerce, tens of thousands of SKUsTop SKUs onlyRecommendedBuild-time render of every variant is impractical. Hybrid often makes sense.
News, live events, hourly updatesNot viableRecommendedDeploy-per-update is infeasible. Per-request rendering is the only honest answer.
Personalized or auth-aware indexable pagesNot viableRecommendedHTML varies per visitor or per logged-in user. Per-request render needed.
SaaS product behind authIrrelevantIrrelevantNot indexable by design. Pick on operational preference; SEO is not the deciding factor.
Already on Next.js, Remix, or NuxtAvailableOne config flagMigration cost is zero in either direction.

"Recommended" means: this is the default unless you have a specific reason otherwise. "Workable" means: it can work, but the other column is usually less painful at this scale.

What we'd tell another small team

Two lessons that did not make it into the pain points:

  • Pick the rendering model that matches the shape of your site, not the framework with the loudest fan club. Most marketing surfaces do not need SSR.
  • Test like a crawler. The fastest way to find out what AI tools see is to run `curl` against your own pages and look at the raw response. If the headline is not there, the page is invisible.

Methodology and verification