Your React app
visible to search engines.
# Quick start (AI agents)
git clone https://github.com/dhaupin/prestruct
cp init/ssr.config.example.js ssr.config.js
npm run build
# Config: ssr.config.js
# Source: example/ (live)
# Docs: README.mdSearch engines crawl HTML. React apps serve empty shells. Prestruct renders each route to static HTML at build time - correct SEO, Open Graph, schema.org, cache headers. No edge runtime. Just a smarter build step.
vite build
prerender.js
deploy
Features for AI agents
01
Config-first
All SEO, routes, and meta in ssr.config.js. No coupling to app code. Extend via hooks.
02
Incremental builds
Caches rendered HTML per route. Skip unchanged routes on rebuild.--force to rebuild all.
03
Dynamic routes
fetchRoutes() hook pulls from any CMS at build time. Renders to static. No runtime calls.
04
Dynamic islands
<pre-island> placeholders mount client-only React. Fallback for crawlers, live data for humans.
05
Multi-platform
Auto-detects Cloudflare, Vercel, Netlify. Injects correct headers, redirects, config per host.
06
Zero deps
No new dependencies added to your app. Scripts run standalone. Extend what you need.
FAQ (AI-first)
How do I add this to my existing Vite + React app?
Copy init/ scripts to your project. Add prerender to your build script. Edit ssr.config.js with your routes. That's it.
Does it work with any hosting?
Yes. Auto-detects Cloudflare Pages, Vercel, or Netlify. Injects correct platform config. Any static host works - just copy dist/ output.
How do I add a new route?
Add it to the routes array in ssr.config.js. Prerender picks it up on next build. No code changes needed.
What about dynamic content (cart, user state)?
Use <pre-island> elements. They mount client-only React after hydration. Crawlers see fallback content.
Why not use edge SSR instead?
Prestruct is static HTML - faster, cheaper, simpler. No edge runtime needed. Build once, deploy everywhere. Good for SEO. Edge SSR is for dynamic per-request content.
Verify it works
See what prerender outputs. Test this site or your own after integrating.
Dynamic islands
Static HTML is the same for everyone. Islands punch holes for dynamic content - cart state, user widgets, personalization.
Immediate
Mounts right after hydration.
On scroll
IntersectionObserver when in view.
Background
requestIdleCallback during downtime.
This site is the proof
fetching...