Deploy a React or Vite App for Free, With a Domain and Form
To deploy a React or Vite app for free, run npm run build and upload the folder it writes (dist/ for Vite) to a static host. On Statpio, drop that folder as a ZIP or run npx statpio deploy ./dist, and it goes live on a free onstatpio.com address with HTTPS, SPA Mode so routes don't 404 on refresh, a contact form that needs no backend and visitor statistics; your own domain needs Solo Pro. Netlify, Cloudflare Pages, GitHub Pages and Vercel's Hobby plan are free too, each with a catch, compared at the end.
Disclosure: this guide is published by Statpio, one of the tools compared. We link every competitor fact to its official source. Framework and host details were checked in their official docs on 9 November 2026.
Which React setups can I deploy as static files?
A React app that renders in the browser can, since it needs no server when someone visits. React's docs say the frameworks they recommend "can be deployed to a CDN or static hosting service without a server" (Creating a React App). Create React App has been deprecated for new apps since 14 February 2025, and React now points to a framework or "a build tool like Vite, Parcel, or RSBuild" (Sunsetting Create React App).
| Your setup | Build command | Folder to upload |
|---|---|---|
| Vite with React | npm run build | dist/ |
| Create React App (maintenance mode) | npm run build | build/ |
React Router framework mode, with ssr: false | react-router build | build/client/ |
Next.js, with output: 'export' | next build | out/ |
Source: Vite static deploy guide, Create React App deployment, React Router SPA guide, Next.js static exports, as of November 2026.
What doesn't move to a static host is code that has to run on a server when someone visits: server-side rendering, API routes, Next.js server actions, an Express server. Statpio hosts static output only. If your app needs those, use a host that runs server code, such as Vercel or Netlify.
How do I build a Vite app for production?
- Run
npm run build. "By default, the build output will be placed at dist." - Check the result with
npm run preview, which servesdistathttp://localhost:4173. Vite says the preview server "is intended for previewing the build locally and not meant as a production server". - Leave
baseat its default,/: Statpio serves each website at the root of its own address. Of the hosts in this guide, only a GitHub Pages project site, served at<user>.github.io/<repo>/, needsbase: '/<repo>/'; any host that serves the app from a sub-folder needs the same.
What about environment variables?
Variables prefixed VITE_ "will be exposed in client-side source code after Vite bundling", and Vite says they "should not contain sensitive information such as API keys" (Env Variables and Modes). A public value such as a publishable key or an analytics ID is fine; a secret needs a server, which a static host doesn't have. Note too that .env.local is meant to stay out of git (Vite says to add *.local to your .gitignore, which its project templates already do), so a build that runs on GitHub doesn't see it: commit public build values in .env instead.
How do I deploy the dist folder to Statpio?
Upload a ZIP (every plan)
- Create a free Statpio account, verify your email, click New website and name it. It gets an address such as
my-app.onstatpio.com, with HTTPS. - Open
dist, select everything inside and compress it, soindex.htmlis at the top of the ZIP. - In Deployments, leave Deployment Type on Static Site and drop the ZIP on Drop your website ZIP here.
Uploads can be up to 25 MB on Free Forever and 50 MB on Solo Pro. Each upload is a new version, and Free Forever keeps the last 5 for one-click rollback. On Solo Pro and up, an upload can go to the website's staging address first, so you can try it before it goes live.
Deploy from the command line (every plan)
- In the website, open Integrations → API Keys, type a key name and click Generate Key. Copy the key: it's shown only once, and it works for that one website.
- Run
npx statpio deploy ./dist --key <website API key>with Node.js 18 or newer. The command zips the folder, uploads it, waits until the new version is live and prints the address.
In CI, store the key as a secret named STATPIO_API_KEY and run npx statpio deploy ./dist after your build step, without --key. It works the same in GitHub Actions, GitLab CI or any runner with Node.js 18.
Push to deploy from GitHub (Solo Pro and up)
- Open Integrations → GitHub Actions, click Install GitHub App and give it access to your repository.
- Choose the repository under Select Repository and the Branch to deploy.
- Keep Install Command as
npm installand Build Command asnpm run build, and set Output Directory to your build folder (distis the default). - Click Connect Repository. Statpio commits
.github/workflows/statpio-deploy.yml, and every push to that branch is built on GitHub Actions and published.
The workflow signs in to Statpio with short-lived GitHub tokens (OIDC), so there's no deploy secret to store in the repository. The publish your website guide has screenshots of these screens.
Why does my React app show a 404 when I refresh a page?
Because the route exists only in the browser. When someone opens /pricing directly, the host looks for a file at that address, finds none and answers 404. React Router's docs put it plainly: "you'll need to configure your host to direct all URLs to the index.html of the client build. Some hosts do this by default, but others don't" (React Router).
On Statpio, that's SPA Mode. It switches itself on when a deploy looks like a single-page app: exactly one HTML page, no 404.html, and build files such as Vite's assets folder. Check it, or turn it on yourself, under Settings → General → SPA Mode. With SPA Mode on, every address that isn't a file opens index.html, so let your router show its own "not found" page. For a site made of separate HTML pages, turn it off: a 404.html in the deploy is then served for missing pages.
Other hosts each have their own way: a /* /index.html 200 rule in a _redirects file on Netlify, a rewrite in vercel.json on Vercel, and automatic on Cloudflare Pages when the project has no top-level 404.html. Statpio doesn't read _redirects or vercel.json; SPA Mode does that job for client-side routes.
How do I add a contact form to a React app without a backend?
Use a plain form and let Statpio do the sending. It captures any form that uses method="POST" with no action, gives every field a name, and has no submit handler of its own: no onSubmit, no preventDefault(), no fetch(). Forms React renders after the page loads, on any route, are set up as soon as they appear.
export default function Contact() {
return (
<form method="POST">
<label htmlFor="name">Name</label>
<input id="name" name="name" type="text" required />
<label htmlFor="email">Email</label>
<input id="email" name="email" type="email" required />
<label htmlFor="message">Message</label>
<textarea id="message" name="message" required />
<button type="submit">Send</button>
</form>
)
}
Statpio adds a visible Cloudflare Turnstile check and a hidden honeypot field itself, so don't add your own. It sends the form in the background, without a page reload, and shows a confirmation. A form with a password field, such as a sign-in form, is left alone. To keep Statpio away from any other form your own code sends, add a hidden input named __statpio_ignore.
Messages, file uploads included, arrive under Forms & Leads, and browser notifications tell you about new ones. Free Forever includes 250 submissions per website a month and Solo Pro 10,000; past the limit, up to the same number again is kept, locked until you upgrade. Test on the live address: capture happens on Statpio's servers, so npm run dev on your computer records nothing.
Visitor statistics need no code: Statpio adds a small cookieless analytics script to every page, and route changes in a single-page app count as pageviews. Every plan shows visitors, sources, pages, countries and devices; Solo Pro adds campaigns, goals, funnels and Core Web Vitals, which in a single-page app are measured on the first load.
How do I connect my own domain?
Custom domains come with Solo Pro ($9/month or $89/year, 5 domains included).
- Open Custom Domains, keep www. Domain, type your domain without the www (
example.com) and click Connect Domain. - At your registrar, create the two CNAME records it shows:
wwwpointing tocname.onstatpio.com, and_acme-challenge.wwwpointing to the validation value from the dashboard, which ends indcv.cloudflare.com. - When the domain shows Active, SSL is set up. Forward
example.comtowww.example.comat your registrar, because Statpio serves root domains throughwww.
Where else can I deploy a React app for free?
| Host | What's free | Your own domain on the free plan | Refreshing a client-side route | The catch |
|---|---|---|---|---|
| Netlify | Free plan: 300 credits a month; a production deploy uses 15 | Yes, with SSL | Add a /* /index.html 200 rule to _redirects | When the month's credits run out, every project pauses |
| Vercel | Hobby plan | Yes, up to 50 per project | Add a rewrite to vercel.json | "Non-commercial, personal use only" |
| Cloudflare Pages | Free plan: 500 builds a month | Yes, up to 100 per project | Automatic when there's no top-level 404.html | One build at a time; 20,000 files per site; Cloudflare now says "Start new projects with Workers" |
| GitHub Pages | Free for public repositories on GitHub Free | Yes | Serves your 404.html for missing pages | Not for an online business or e-commerce site; a project site needs base set |
| Statpio | Free Forever: 1 website on onstatpio.com | No: Solo Pro, $9/month | SPA Mode, on by itself for a typical build | A Statpio badge on Free Forever; forms and statistics included |
Source: Netlify pricing and credits; Vercel Hobby plan and Vite on Vercel; Cloudflare Pages limits and serving; GitHub Pages overview, limits and 404 page; Statpio pricing. As of November 2026.
Which one fits depends on the project. All four free plans let you use your own domain. For a commercial site, rule out Vercel's Hobby plan (personal, non-commercial use only); for a shop or a site that runs your business online, rule out GitHub Pages too; Netlify's Free plan allows commercial projects, within its monthly credits. If the app needs server-side rendering or API routes, use a host that runs server code, such as Netlify, or Vercel on its Pro plan for commercial use. Statpio fits when the app needs a contact form and visitor statistics without adding other services, or when you run several small sites: Solo Pro covers 5 websites. Our Statpio vs Vercel comparison goes into the details.
Ready to deploy?
If npm run build gives you a dist folder, you can start free on Statpio, upload it, refresh a few inner routes and send a test message before you pay for anything. Hosting a site without a build step? See how to host an HTML website free, with forms and analytics.
Frequently asked questions
How do I deploy a React app for free?
Run npm run build and upload the folder it writes (dist for Vite, build for Create React App) to a static host. On Statpio's Free Forever plan it goes live on a free onstatpio.com address with HTTPS, form capture and visitor statistics. Netlify, Cloudflare Pages and GitHub Pages also have free plans, and Vercel's Hobby plan is free for personal, non-commercial use.
Why does my React Router app show a 404 when I refresh?
The route exists only in the browser, so the host finds no file at that address. The host has to serve index.html for those addresses. On Statpio that's SPA Mode, which switches itself on for a typical Vite build and can be checked under Settings, General. Netlify uses a _redirects rule, Vercel a rewrite in vercel.json, and Cloudflare Pages does it automatically when there's no top-level 404.html.
Can I deploy a Vite app with a custom domain?
Yes. On Statpio, custom domains come with Solo Pro at $9/month, with 5 domains included: add the domain on the Custom Domains page and create two CNAME records at your registrar, and SSL is set up automatically. The Free Forever plan uses a free onstatpio.com address instead.
How do I deploy a React app to GitHub Pages?
Vite's guide says to set base to your repository name with slashes for a project site, choose GitHub Actions as the Pages source in the repository settings, and add a workflow that runs npm run build and uploads dist. GitHub Pages is free for public repositories on GitHub Free, but GitHub says it isn't meant to run an online business or e-commerce site.
Can a React app have a contact form without a backend?
On Statpio, yes. Render a plain form with method POST, no action attribute, a name on every field and no onSubmit, preventDefault or fetch of your own. Statpio captures it on every plan, including forms React renders after the page loads, adds spam protection and puts the messages in your dashboard: 250 per website a month on Free Forever.
Should I still use Create React App?
Not for a new app. React deprecated Create React App for new apps on 14 February 2025 and recommends a framework, or a build tool such as Vite, Parcel or Rsbuild. An existing Create React App project still builds to a build folder, which deploys to a static host the same way.
Keep reading
Related articles

Deploy an Older Lovable, Bolt or v0 Site on Your Own Domain
Built with Bolt.new, v0, Cursor or Claude, or a Lovable project made before 13 May 2026? Find out what kind of app you have, build it, upload it and connect your own domain.
Read nextHow to Deploy a Google AI Studio Website for Free
Google AI Studio can publish your app to Cloud Run, free on the Starter Tier for eligible accounts. If the app runs entirely in the browser, you can skip Cloud Run and host its build on a static host, with a contact form and visitor statistics.
Read next
How to Host an HTML Website Free, With Forms and Analytics
A step-by-step guide to putting a folder of HTML online with a working contact form and visitor analytics, without a backend. Includes the exact form code, the DNS records for your own domain and what the free plan covers.
Read nextHow to Publish a Claude Artifact as a Real Website
Claude shares an artifact as a link to a page Anthropic hosts. To put it on a website of your own, export the HTML or let Claude publish it through the Statpio connector, then add a form that works and visitor statistics.
Read next