ADR-004: React SPA on Cloudflare Pages
Status: Accepted
Date: 2026-02-01
Deciders: Abdisamed Mohamed
Related ADRs: ADR-002 (Edge-First Architecture)
Context
CepatEdge requires dynamic client-side routing for maintenance request details, user profiles, and administrative interfaces. Traditional static site generators have limitations with dynamic routes, while full server-side frameworks add unnecessary complexity and cost.
The application needs:
- Dynamic routing (e.g.,
/maintenance/:id,/users/:id) - Client-side navigation
- Component reusability
- TypeScript support
- Minimal operational overhead
Decision
Use React SPA deployed on Cloudflare Pages with client-side routing.
Implementation
Technology Stack
typescript
// Client-side routing with React Router
import { BrowserRouter, Routes, Route } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/maintenance/:id" element={<MaintenanceDetail />} />
<Route path="/users/:id" element={<UserProfile />} />
<Route path="/admin/*" element={<AdminRoutes />} />
</Routes>
</BrowserRouter>
);
}Build Configuration
javascript
// vite.config.js - React SPA build for Pages
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
build: {
outDir: 'dist',
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
router: ['react-router-dom']
}
}
}
},
server: {
port: 3000,
host: true
}
})Deployment
- Build Command:
npm run build(Vite production build) - Output Directory:
dist/ - Routing: Client-side routing handles all dynamic paths
- CDN: Automatic global distribution via Cloudflare Pages
Consequences
Positive
- Dynamic Routing: Support for
/maintenance/:idstyle routes without server - Client-Side Navigation: Fast navigation without page reloads
- Component Architecture: Reusable React components with TypeScript
- Zero Server Cost: No server-side rendering overhead
- Global CDN: Automatic content delivery worldwide
Negative
- SEO Limitations: No server-side rendering for search engines
- Initial Load: Larger initial bundle size
- Hydration: Client-side only, no SSR benefits
- API Calls: All data fetching happens client-side
Mitigation
- Static Generation: Critical pages pre-generated where possible
- Code Splitting: Lazy loading for optimal bundle sizes
- API Optimization: Efficient data fetching with SWR
- Service Worker: Offline capabilities for better UX
Alternatives Considered
Next.js with Server Components
- Pros: Better SEO, streaming, server components
- Cons: Requires server infrastructure, higher cost, complexity
Next.js Static Export
- Pros: Familiar framework, good developer experience
- Cons: Framework overhead, limited customization, build complexity
Traditional React SPA (Vite + Vercel)
- Pros: Fast development, modern tooling
- Cons: Regional deployment, potential latency issues
Static Site Generator (Astro, SvelteKit)
- Pros: Fast builds, good performance
- Cons: Limited dynamic routing, framework lock-in
Cloudflare Pages Functions
- Pros: Server-side logic at edge
- Cons: Additional complexity, cost implications
Performance Benchmarks
Bundle Size
- Initial Load: <200KB gzipped
- Lazy Chunks: <50KB per route
- Total: <500KB for full application
Routing Performance
- Client Navigation: <50ms
- Data Fetching: <100ms with caching
- Page Load: <300ms globally
References
- Cloudflare Pages Documentation
- React Router Documentation
- Vite Build Tool Documentation
- Performance benchmarks with Lighthouse