16Docs
Domains
Give your hosted app a shareable URL: a vanity <slug>.bounded.page (free), or your own custom domain (Pro). Your appId stays in project config and CLI flags; it is not the URL you publish to users.
Publish the built web client
Build the client-rendered UI, then publish its output directory on the same Bounded app as the policy and runtime:
npm run build
bounded site deploy ./dist --app-id <id>
bounded domains slug myapp --app-id <id>Vanity subdomain (free)
Claim one canonical vanity subdomain for your app. This is the default public Bounded URL to share before you add a custom domain.
bounded domains slug myapp --app-id <id> # → https://myapp.bounded.page
bounded domains slug --release --app-id <id> # free it| Rule | Behavior |
|---|---|
| Globally unique | A slug is a subdomain. Taken names are rejected with a suggested alternative. |
| One per app | Changing the slug frees the old one; your appId remains the stable internal project id. |
| Reserved names blocked | www, api, auth, admin, … and appId-shaped names are rejected. |
| Auth just works | The slug is added to your app’s allowedOrigins automatically (CORS + login). |
| API too | <slug>-api.bounded.page is the Bounded-managed API hostname for that app. |
Custom domain (Pro)
Bring a domain you own. Bounded issues the SSL cert (Cloudflare for SaaS); you add a couple of DNS records and it validates automatically.
bounded domains add app.yourdomain.com --app-id <id> # prints DNS records to add
bounded domains list --app-id <id> # pending → active
bounded domains remove app.yourdomain.com --app-id <id>Flow: add returns the DNS records (a CNAME + ownership / SSL TXT records) to paste at your registrar. Once DNS propagates the cert validates, list flips the domain to active, and https://app.yourdomain.com serves your app (added to allowedOrigins). remove tears it all down.
How it routes
All app assets are keyed by appId internally. At the edge, a request's host is resolved to an appId: a vanity slug and a custom domain both resolve to your app and serve the same deployed assets. Each host maps to exactly one app; an unmapped host returns 404 (fail-closed). A domain can never serve the wrong app.