Skip to content

Deploy a Static Site ​

A Static Site is for an app with no server of its own — a built React/Vue/Svelte bundle, or plain HTML/CSS/JS. Infrly runs your build once, then serves the resulting files directly over HTTPS. Nothing keeps running afterward, which is what makes static sites cheaper than a Web Service and immune to ever crashing at runtime.

If your app needs a server-side process (an API, background work, anything that has to keep running), that's a Web Service instead.

Create the service ​

New Service → Static Site, then fill in:

FieldMeaning
Repository / Branch / Root directorySame as a Web Service — see Deploy a Web Service.
Build commandE.g. npm run build. Runs once per deploy; there's no start command, since nothing keeps running afterward.
Output directoryWhere your build writes its static files, relative to the root directory — dist for Vite and Astro, build for Create React App, out for a static Next.js export, .output/public for Nuxt (built with nuxt generate). Infrly prefills it for frameworks it recognizes. Infrly publishes exactly this folder's contents.

Environment variables work differently here ​

This is the part that trips people up: a Static Site build does not receive the environment variables you set in the dashboard's Environment Variables panel. That panel's "build variable" toggle exists, but nothing in a static site's build pipeline reads it today — a value you enter there is saved, but never reaches npm run build (or any other build command).

Since a static site has no server running afterward either, there's no runtime moment where a dashboard-configured value could reach your app "after the fact" the way it would for a Web Service. The build itself is the only point where a value can ever reach a static site — so it has to go into the Build Command field directly, as a literal, inline value:

VITE_BACKEND_URL=https://my-api-ab12cd.infrlyapp.com npm run build

Infrly runs your build command as a real shell command, so this works exactly like it would in a terminal — the assignment applies to that one command. Most bundlers expose variables set this way to your app code under their own convention (Vite: anything prefixed VITE_, via import.meta.env.VITE_BACKEND_URL; Create React App: prefixed REACT_APP_, via process.env.REACT_APP_BACKEND_URL) — check your bundler's docs for its exact prefix.

Changing the value later

Because the value is baked into the built files, changing it means editing the Build Command and triggering a new deploy — there's no "restart to pick up a new env var" for a static site the way there is for a Web Service, since nothing is running to restart.

Talking to a Web Service backend

If your static site calls a separate backend (a Web Service in the same or a different project), deploy the backend first, copy its public URL, then use it in your static site's Build Command as shown above.

Clean URLs and client-side routing ​

Infrly serves your output directory's files directly, with a client-side-router-friendly fallback to index.html for paths that don't match a real file — a hard refresh on /dashboard/settings in a React Router / Vue Router app lands correctly on your app shell instead of a 404, the same as any other static host.

What happens when you deploy ​

QUEUED → CLONING → PACKAGING → CONFIGURING_DOMAIN → CONFIGURING_SSL → RUNNING

Shorter than a Web Service's pipeline: no DEPLOYING/STARTING/HEALTH_CHECKING, since there's no running process to start or health-check — a static site is either successfully published or it isn't. If the build itself fails, the log shows the exact command and output that failed, the same as a Web Service's build phase.

No runtime logs

A static site has no request/error logs after it's deployed, because nothing runs after the build — the build log is the only log a static site ever has. See Deployment & Runtime Logs.

Next ​

Infrly — You commit. We ship. Need something custom? support@infrlyapp.com