Examples
Real-world usage patterns and project structure.
Project structure
Typical prestruct project:
my-app/
├── src/
│ ├── App.jsx # Main app with BrowserRouter
│ ├── AppLayout.jsx # Layout component (no BrowserRouter)
│ ├── routes/
│ │ ├── Home.jsx
│ │ ├── About.jsx
│ │ └── Blog.jsx
│ └── islands/
│ └── Cart.jsx # Dynamic island component
├── scripts/
│ ├── prerender.js # Build-time prerender
│ └── proxy.js # Optional bot proxy
├── ssr.config.js # Prerender configuration
├── wrangler.toml # Cloudflare Pages config
└── package.json
Static site with islands
Extract AppLayout from your app to separate the prerenderable portion:
// AppLayout.jsx - renders at build time
import { Routes, Route } from 'react-router-dom'
export default function AppLayout() {
return (
<div>
<nav>...</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
<footer>...</footer>
</div>
)
}
Dynamic island component
Wrap client-only components in <pre-island> for hydration after load:
// islands/Cart.jsx
export default function Cart() {
const [items, setItems] = useState([])
return (
<pre-island data-pre-load="visible">
<CartWidget items={items} />
</pre-island>
)
}
Mount in client entry:
// main.jsx
import { mountIslands } from './islands'
mountIslands()
Deploy to Cloudflare Pages
Build and deploy:
# Build
npm run build
# Deploy
wrangler pages deploy dist
With proxy
For dynamic routes or frequent content updates:
- Set config.proxy.url in ssr.config.js
- Deploy proxy worker
- Point Cloudflare Pages to proxy URL
See Proxy for full setup.