Launching today

snappy-prerender
Turn your existing SPA into static HTML
2 followers
Turn your existing SPA into static HTML
2 followers
snappy-prerender opens every route of your built SPA in a real browser at build time and writes static HTML. Keep your framework, router, build and deploy. Adds per-route SEO, sitemap, audit, hydration checks, CSP and preload hints.




Free
Launch Team

AWS Startup AdvisorPersonalized AWS guidance that meets you where you’re already building
Promoted
Hey Product Hunt,
I maintain several apps: CRA, React 18, client-side routing, CMS content. SEO and OG tags need real HTML, and a client-side app gives crawlers an empty page.
I built snappy-prerender as a replacement for react-snap to ease my headaches. It is now a framework-agnostic static site generator for apps you already have.
At build time it opens each route in a browser, follows links, writes static HTML, and checks that the client uses it. It also writes per-route SEO and sitemap data, audits the output, verifies hydration, and accepts routes from a file or sitemap. React, Vue, Svelte and Preact are supported. You keep your framework, router, build and deploy.
It is not SSR. New content needs a build. It is not for Next.js, Remix or Astro, and it will not fix pages that render differently on every load; it reports the route and first mismatch.
Or run it from vite build with the Vite plugin. If you have an old SPA, React or not, try it and tell me what breaks.
One command after your normal build. Point it at dist, build, or any static output. No SSR entry, router migration, or app rewrite.
Real browser rendering. Every route is loaded in Chrome/Edge/Chromium, allowed to settle, then serialized to static HTML.
Hydration verification. Every written page is reloaded with the client bundle and reported as hydrated or re-rendered, with framework-specific errors and the first DOM mismatch.
SEO without React Helmet. Titles, descriptions, canonical, Open Graph, Twitter, JSON-LD, hreflang, arbitrary head tags, and html/body/title attributes — with restoration on client navigation.
Client-side head parity. Covers the React Helmet / Helmet Async surface for prerendered apps: defaultTitle, multiple images, duplicate metas, onChangeClientState, and React 19 native tag adoption.
Locales and hreflang. Path or single-locale builds, canonical URLs, og:locale, x-default, sitemap alternates, and cookie/localStorage SEO locale seeding.
Site audit. Broken internal links, metadata gaps, duplicate titles/descriptions, heading problems, sitemap disagreement, CSP violations, and orphan pages.
Faster static output. Critical CSS, inline CSS, HTML/CSS minification, preconnect hints, image preload, modulepreload, a preload manifest, and cached AJAX state.
Deterministic builds. Freeze time, set timezone, seed Math.random, and honour SOURCE_DATE_EPOCH so repeated builds stay stable.
Explicit hydration policies. Allow a re-render or skip verification for genuinely live routes instead of disabling the check globally.
Flexible route sources. Crawl, explicit routes, text/JSON files, sitemaps, route priorities, depth limits, and route overrides.
CI-friendly. Versioned JSON reports, audit gates, hydration gates, failure traces, screenshots, and authenticated route support.
Works with the stack you already have. React 16.8, 17, 18 and 19; Vite 6, 7 and 8 + CRA; Vue, Svelte and Preact; Angular, Solid, Lit, Ember, vanilla JavaScript, or any other client-rendered SPA.