Skip to main content
slipway runs your build command, uploads the directory it produces, and serves those files from the edge. A static site has no container, so it has no compute allocation and nothing to pay for by the minute. You are metered on bandwidth only.
slipway.yaml
Push to the tracked branch and it rebuilds. The new build goes live the moment its upload finishes.

publish

Required. The directory your build writes, relative to rootDir.
slipway.yaml
Common values: Getting this wrong is the most common way a static site fails: the deploy goes green and the URL returns 404. The build log reports how many files were uploaded, and the service’s Files view lists exactly what is there.

The build

rootDir is where the build runs, defaulting to the repository root. buildCommand is what it runs, and needs runtime to say what to run it in.
slipway.yaml
Dependencies are installed before buildCommand runs, from whichever lockfile the project commits: npm ci, pnpm install or yarn install for Node, pip install for Python, bundle install for Ruby. The build command is only the build. Writing npm ci && npm run build still works, it just installs twice. All four settings can be changed later from the site’s Settings tab, under Build. Saving rebuilds and republishes the site. A site that deploys from a committed slipway.yaml shows the file’s values there, and is changed in the file. Omit buildCommand when the files are already committed and need no build:
slipway.yaml
dockerfilePath, dockerContext, dockerTarget and image are all rejected on a static service. No image is built and none is pulled.

Uploading a build instead

A static site is the one thing slipway serves with no repository, because the artifact is the whole input. In New → Static site, switch the source to Upload a build and drop a .zip of your build output. Re-upload at any time to publish a new version. Each upload replaces the last, and deploying publishes it the same way a repo build would, with the same events, rollback and file views. A zip made by compressing a directory wraps everything in one top-level folder. slipway strips a single wrapper automatically, so both of these serve the same site:
Two or more top-level entries are treated as the site itself rather than a wrapper. __MACOSX/ and .DS_Store are skipped, and an archive containing .. in a path is rejected rather than relocated. An uploaded site has no build command, no build-time environment variables and no branch to watch, so nothing auto-redeploys. Everything else on this page works identically.

Environment variables

A static site has no runtime, so env applies to the build only.
slipway.yaml
That is the common case: a frontend baking in the URL of an API it deploys alongside. The reference resolves at deploy time, before the build runs.
Anything referenced here ends up inside the built files, which are public by definition. Bundlers inline environment variables at build time, so a ${secret.*} reference here is readable by anyone who views source. Do not put secrets in a static site’s env.

Single-page apps

Set notFound to your entry document so client-side routes resolve.
slipway.yaml
Requests that match no file are served index.html. Requests that look like assets, a dotted filename that is not .html, still return a real 404, so a missing /app.js does not come back as HTML and surface as a JavaScript syntax error. For a multi-page site, point notFound at a real error page instead:
slipway.yaml
A 404.html in the publish directory is used automatically even without notFound, and the nearest one wins, so docs/404.html answers misses under /docs/.

Redirects and headers

slipway.yaml
A real file beats a 200 rewrite; set force: true to override that. A 3xx rule beats a real file, so you can retire a live URL without deleting the page behind it. An empty header value removes the header. slipway also reads _redirects and _headers files from the publish directory, in the Netlify and Cloudflare Pages format, so a site moving from either platform works unchanged. A syntax error there does not fail the deploy: the bad line is skipped and named in the build log. The files themselves are never served. The same rules can be edited in the console without a rebuild. See Redirects and headers for how the three sources combine and which wins.

Caching

slipway sets caching for you:
  • Hashed assets, meaning anything under /assets/, /_app/immutable/, /_next/static/, or with a content hash in the filename, get Cache-Control: public, max-age=31536000, immutable.
  • Everything else revalidates, so a deploy is visible immediately.
Override either with a headers rule. You never need to purge a cache. Each deployment’s files are served from their own address at the edge, so a deploy or rollback moves to fresh cache entries rather than invalidating old ones.

Deploys and rollbacks

A deploy is atomic. The previous build serves until the new one is completely uploaded, then the switch happens between requests. Rolling back rebuilds nothing, because the previous build’s files are still there, so it is a single pointer change. Older builds are kept for 30 days and at least the last 10, which is how far back you can roll. A switch takes a few seconds to reach every location and up to about a minute worldwide. Nobody ever sees a mixture of two builds.

Custom domains

Add the domain on the project’s Settings → Domains, then point one DNS record at slipway:
The certificate is issued and renewed automatically once that record resolves. For a root domain, DNS does not allow a CNAME at the apex. If your provider supports ALIAS, ANAME or CNAME flattening, use the same target with that record type. If it does not, slipway shows A records to use instead, or you can redirect the apex to www. See Custom domains.

Traffic

A static site is served from the CDN and the cluster is never in the request path, so there are no pod counters and nothing for the Metrics tab to sample. Its traffic is measured at the edge instead, and shows up in two places. The site’s own page carries Egress and Requests for the last 24 hours, hour by hour, along with how those requests were answered. An hour that is tall on requests and flat on egress is a site answering 304 Not Modified, which means caching is working. The project overview adds a CDN panel whenever the project runs any static services, with one bar per hour and a colour per site. It sits beside CPU, Memory and Requests rather than joining them: those cover the project’s containers at five-minute resolution, and edge traffic is only reported by the hour. Drawing the two on one axis would make a site serving the same rate as a container look twelve times busier. Edge measurements arrive a couple of minutes behind, so the most recent bar keeps filling in for a short while after a burst.

What a static site does not have

No shell, no scaling, no disks, no compute allocation and no sleep, because there is no container for any of those to act on. The console hides those tabs rather than locking them. Siblings cannot reach a static site over the private network. There is no http://site inside the project because no process is listening, and ${service.site.host} fails with a message pointing at ${service.site.public_url}.

Pricing

Static sites are not billed for compute, and their builds are free. You pay for egress beyond your plan’s allowance. See Plans.