Deploy React on Your Own Server
Deploy your React app and Temps serves it from the edge — running npm run build, serving the dist/ or build/ output with gzip and brotli compression, and routing all paths through index.html for client-side navigation.
Quickstart
From your project root, deploy with your preferred package manager:
npx @temps-sdk/cli up
Temps auto-detects Vite and CRA, runs npm run build, and serves the dist/ or build/ output. Your app is live with HTTPS in about 2 minutes.
What Temps handles automatically
| Feature | How Temps handles it |
|---|---|
| Build | npm run build |
| Output | Serves dist/ (Vite) or build/ (CRA) |
| HTTPS | Let's Encrypt certificate, auto-renewed |
| Client-side routing | 404 → index.html fallback configured automatically |
| Cache headers | Hashed assets get long-lived cache headers |
| Compression | gzip and brotli enabled |
| Preview deployments | Every PR gets its own URL |
Environment variables
Vite environment variables (prefixed VITE_) are embedded at build time:
npx @temps-sdk/cli environments vars set VITE_API_URL "https://api.example.com" -e production
A new deployment is triggered when you update build-time variables.
Backend API
If your React app calls a backend API, deploy your backend as a separate Temps project and set VITE_API_URL to its URL. For full-stack apps in a monorepo, set the App Directory in project settings for each app — see Deploy a Project.
SPA routing
Single-page applications use client-side routing — paths like /about or /dashboard/settings do not correspond to files on disk. The Temps proxy handles this automatically.
When a request arrives for a path that:
- Has no file extension (e.g.
/about, not/about.css) - Does not match any file on disk
…the proxy serves index.html instead, and your client-side router (React Router, Vue Router, etc.) takes over. This works out of the box — you do not need _redirects, vercel.json, or any rewrite rules.
Compression and caching
The Temps proxy applies performance optimizations to all static file responses automatically:
- Gzip compression for text-based files over 1 KB (HTML, CSS, JavaScript, JSON, XML, SVG) when the browser supports it.
- ETags based on each file's content hash, so unchanged files return
304 Not Modified.
Cache-Control headers are set based on the file path:
| Pattern | Cache-Control | Use case |
|---|---|---|
/assets/*, /static/*, /_next/static/*, .chunk.*, .hash.* | public, max-age=31536000, immutable | Hashed assets that never change |
| Everything else | public, max-age=0, must-revalidate | HTML files and non-hashed resources |
Your hashed JS and CSS bundles are cached for a year, while index.html is always revalidated so new deployments are picked up immediately.