shiply.now

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

FrameworkBuild outputSPA mode
Next.js (output: 'export')out/no
Astrodist/no
SvelteKit (adapter-static)build/yes
Vite (React/Vue/Svelte/Solid/Qwik)dist/yes
Create React Appbuild/yes
Nuxt (nuxt generate).output/public/no
Remix (client build)build/client/yes
Docusaurusbuild/no
Hexopublic/no
SolidStart (static preset)dist/public/no
Qwik City (static adapter)dist/no
Hugopublic/no
Jekyll_site/no
Eleventy_site/no
MkDocssite/no
Plain HTML / pre-built outputany folder with index.htmloptional

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 --spa

Next.js (static export)

Add to next.config.ts:

const nextConfig = { output: 'export' }

Then:

npm run build
shiply publish out

No --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 dist

SvelteKit

Use @sveltejs/adapter-static, then:

npm run build
shiply publish build --spa

Nuxt

nuxt generate produces a fully pre-rendered static site:

npx nuxt generate
shiply publish .output/public

Remix

For a static client build (no server runtime):

npm run build
shiply publish build/client --spa

Remix server features (loaders running at request time, actions) are not served — only the pre-built client assets.

Docusaurus

npm run build
shiply publish build

Hugo / 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 site

Hexo / 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 dist

Override detection

If auto-detection picks the wrong framework, force it:

shiply publish . --framework=astro

Run 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.