All articles

How to deploy a React or Vite build the easy way

August 31, 2026 7 min read

your file
one link
Turn any file into a clean, shareable link in seconds.

You ran npm run build, watched it churn, and got a dist/ folder. That folder isyour app — every route, every component, compiled down to static files. The only thing between it and a public URL is "somewhere to put it," and that step is usually wrapped in far more ceremony than it needs. Here's the easy way, plus the two details that actually matter for a front-end build.

Your build is already a static site

This is the key realization: a production front-end build is, by design, a folder of static files. Vite writes dist/, Create React App writes build/, a static export writes out/ — each an index.htmlplus fingerprinted JavaScript and CSS bundles and your assets. No server is required to serve them. So you don't need a deploy platform with a build pipeline; you need somewhere to drop the files.

The easy way

  1. Build. Run npm run build(or your tool's equivalent).
  2. Zip the output folder. Compress dist/ (Vite), build/ (CRA), or out/ (static export). Zipping the whole project is fine too — the output folder is detected automatically.
  3. Upload the ZIP. Every file is served with the right type — your bundle as text/javascript, styles as text/css, fonts as font/woff2 — which is exactly what the browser needs to boot the app.
  4. Turn on SPA mode, add your domain. Enable single-page-app fallback for client-side routing, and on Pro connect your own domain with automatic SSL.

Detail #1: client-side routing needs a fallback

A single-page app routes in the browser. Your React Router or Vue Router owns /dashboard and /settings — there are no dashboard.html files on disk. So when a visitor opens a deep link directly, or hits refresh on an inner page, the server has to hand back index.htmlso your router can take over. That's what single-page-app modedoes: unknown paths fall back to index.html with a 200, so refreshes and shared deep links resolve instead of returning a 404. If you're building a plain multi-page site, leave it off and unknown paths return a real 404 (or your own 404.html).

Symptom to recognize: the app works when you click into a route from the home page, but a hard refresh or a pasted deep link 404s. That's the SPA fallback missing — turn it on and it's fixed.

Detail #2: caching hashed bundles the right way

Your bundler fingerprints filenames — index.4f3a9c2b.js — precisely so they can be cached aggressively: the name changes whenever the contents do. The correct setup caches those content-hashed assets with a one-year immutable cache, so repeat visits load instantly from cache, while index.html is served no-cache so a new deploy shows up immediately. Done right, you get the speed of hard caching without the classic stale-HTML bug where an old page points at bundles that no longer exist. Ship an update by uploading a fresh ZIP — same URL, new version on the next load.

What's out of scope

Static hosting serves your built files and nothing else. Calls from the browser to an external API over HTTPS keep working. What doesn't: anything that needs a server at request time — Next.js server components rendered per request, SvelteKit endpoints, server middleware, secrets read on the server. For those, export a fully static build or use a platform that runs the server. Bring built static output and you get a fast, simple host; bring a server-dependent app and this is the wrong tool.

Ship it

Build, zip dist/, and drop it on the deploy a Vite or React build page. If you just want a built site online in general, the host a static website guide covers the same flow, and publish an HTML ZIP is the plain-HTML version.

Turn any file into a link in seconds

Upload a PDF, image, video, or ZIP and get a clean, trackable link with a QR code — free.

Try Link in Seconds →