Deployment

A Zoijs app is just static files — HTML, CSS, and JavaScript. "Deploying" means copying them to any static host.

Static hosting#

A Zoijs app is plain static files, so upload your folder (an index.html, your app.js, CSS, and assets) to any static host. Get the framework from a CDN with an import map, or vendor the package sources into your project.

Always pin the exact versions you import (@zoijs/core@1.9.0, not @1 or @latest) with an integrity hash for every module, or vendor them. Deploy with the production entry, …/src/prod.js. See Installation and the Production Security checklist.

Cloudflare Pages#

This very site deploys to Cloudflare Pages. Two files make it production-ready:

_redirects — SPA fallback#

If you use the router, a hard refresh of a deep link (e.g. /getting-started) asks the server for that path. There's no such file, so without a fallback you'd get a 404. Tell Cloudflare to serve index.html for unknown paths:

/* /index.html 200

In-app navigation needs no configuration; only full reloads of deep links do.

_headers — security headers#

/*
  Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net 'sha256-REPLACE_WITH_YOUR_IMPORT_MAP_HASH'; object-src 'none'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin

Hash the exact contents of your inline import map, and add style-src-attr 'unsafe-inline' only if your templates use style attributes. The full, copy-paste policy for every host is in the Production Security checklist.

Connect the repo#

In the Cloudflare dashboard: Pages → Create → Connect to Git, pick your repo, set the build command to empty (none) and the output directory to your site folder. Deploy.

App base path vs route path#

Hosting at a domain root (zoijs.dev)? No base needed. Hosting under a sub-path (a project page)? Tell the router with base so your route patterns stay clean:

createRouter(routes, { base: "/my-app" });

You configure two different things: base in your app code, and the fallback on your host. A sub-path app needs both.

Other hosts#

The same idea (serve index.html for unknown paths) applies to Netlify, Vercel, Nginx, and Apache. A concrete, copy-paste GitHub Pages recipe walks through deploying the Task Board end to end.