Your React app
visible to search engines.

sh
# 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.md

Search 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

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.

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.

Static HTML is the same for everyone. Islands punch holes for dynamic content - cart state, user widgets, personalization.

eager

Immediate

Mounts right after hydration.

visible

On scroll

IntersectionObserver when in view.

idle

Background

requestIdleCallback during downtime.

https://prestruct.creadev.org is the example app in the Prestruct repo. Build, deploy, inspect - it's all running the same prerender pipeline you're copying.
live head tagshttps://prestruct.creadev.org/

fetching...