Deploy any static site
Host any framework — Astro, SvelteKit, Hugo, Jekyll, Next.js export, and more — by publishing the build output
shiply hosts any static site, not just plain HTML pages. The one rule: publish the build output, never the source code. When you build a framework app or run a static site generator, the output folder is a static site — HTML, hashed JS bundles, CSS, assets — and shiply serves it from the edge.
The CLI auto-detects 16+ frameworks. Run shiply publish . in your project
and it either publishes the build output for you (with the right flags) or
prints the exact build command to run first. Preview what it found with
shiply detect.
Auto-detected frameworks
| Framework | Build output | SPA mode |
|---|---|---|
Next.js (output: 'export') | out/ | no |
| Astro | dist/ | no |
| SvelteKit (adapter-static) | build/ | yes |
| Vite (React/Vue/Svelte/Solid/Qwik) | dist/ | yes |
| Create React App | build/ | yes |
Nuxt (nuxt generate) | .output/public/ | no |
| Remix (client build) | build/client/ | yes |
| Docusaurus | build/ | no |
| Hexo | public/ | no |
| SolidStart (static preset) | dist/public/ | no |
| Qwik City (static adapter) | dist/ | no |
| Hugo | public/ | no |
| Jekyll | _site/ | no |
| Eleventy | _site/ | no |
| MkDocs | site/ | no |
| Plain HTML / pre-built output | any folder with index.html | optional |
Anything else that produces a dist/, build/, out/, _site/, public/,
or .output/public/ folder with an index.html is picked up by the generic
fallback.
React / Vue / Svelte / Solid / Qwik (Vite)
npm run build
shiply publish dist --spa--spa makes deep links like /about fall back to index.html, so the
client router handles the route instead of 404ing.
Create React App
npm run build
shiply publish build --spaNext.js (static export)
Add to next.config.ts:
const nextConfig = { output: 'export' }Then:
npm run build
shiply publish outNo --spa needed — export writes a real HTML file per route. Note that
server-only features (getServerSideProps, route handlers, server actions)
are not part of a static export; for API calls with secrets, use
Variables and the upcoming proxy routes.
Astro
npm run build
shiply publish distSvelteKit
Use @sveltejs/adapter-static,
then:
npm run build
shiply publish build --spaNuxt
nuxt generate produces a fully pre-rendered static site:
npx nuxt generate
shiply publish .output/publicRemix
For a static client build (no server runtime):
npm run build
shiply publish build/client --spaRemix server features (loaders running at request time, actions) are not served — only the pre-built client assets.
Docusaurus
npm run build
shiply publish buildHugo / Jekyll / Eleventy / MkDocs
Classic static site generators. Build, then publish the output folder —
no --spa flag (every route is a real HTML file):
# Hugo
hugo && shiply publish public
# Jekyll
bundle exec jekyll build && shiply publish _site
# Eleventy
npx @11ty/eleventy && shiply publish _site
# MkDocs
mkdocs build && shiply publish siteHexo / SolidStart / Qwik City
# Hexo
npx hexo generate && shiply publish public
# SolidStart (static preset in app.config.ts)
npm run build && shiply publish dist/public
# Qwik City (with @qwik-city/static adapter)
npm run build && shiply publish distOverride detection
If auto-detection picks the wrong framework, force it:
shiply publish . --framework=astroRun shiply detect to see what was matched, which build command will run,
and which folder will be published — without uploading anything.
Updates keep the same URL
Re-running shiply publish in the same directory updates the same site at
the same URL — state lives in .shiply.json next to your build output, and
unchanged hashed bundles are skipped, so updates upload only what changed.
Tips
- Agents: prefer the CLI over inline MCP uploads for built apps — a production build often has 100+ hashed files, beyond the 50-file inline cap.
- Limits: 1,000 files per site, 100 MiB per file, 1 GiB per site.
- Calling APIs that need a secret key? Don't embed keys in your bundle — store them in Variables.