Deploy a PRISM Site

Deploying a PRISM site is three steps: build it, bind a domain (which mints the TLS certificate and writes the vhost in one call), then evict the edge route table so the new host is served. For subdomain conventions and multi-tenant hosting, see Subdomains.

Where sites live

A deployed site lives under a sites/<name>-prism/ directory. That directory is the root you bind a domain to below.

1. Build

Produce the production bundle into dist/:

bext build

See the CLI Reference for bext build and bext run.

2. Bind the domain

One loopback call provisions everything. POST /__bext/sdk/vhost/upsert_auto mints the Let's Encrypt certificate (ACME HTTP-01, reusing an existing cert when it still has more than 30 days of validity), writes the vhost, and reloads — atomically:

curl -X POST http://127.0.0.1/__bext/sdk/vhost/upsert_auto \
  -H "X-Bext-App-Id: my-app" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "my-app.inklura.fr",
    "root": "/srv/sites/my-app-prism",
    "email": "ops@inklura.fr"
  }'
Field Required Notes
domain yes The hostname to serve.
root yes Absolute path to the sites/<name>-prism/ directory.
email no ACME account / expiry-notice address.
Info

This is a loopback SDK endpoint — call it from the host over 127.0.0.1 with the X-Bext-App-Id header identifying your app. It is not reachable from outside the box.

DNS and TLS are automatic for *.inklura.fr

Wildcard DNS for *.inklura.fr already resolves, so a new <something>.inklura.fr needs no DNS change. TLS is issued automatically by the call above. Point a subdomain at your site and it is live over HTTPS.

3. Evict the edge route table

After adding a new site, evict the edge route table so the router starts serving the new host:

curl -X POST http://127.0.0.1:8444/nginx-cache/purge-site \
  -H "Content-Type: application/json" \
  -d '{"host":"my-app.inklura.fr"}'

Skip this and the new host may not resolve to your site yet.

Live reload

With live_reload = true and your source under [build] watch_dirs, the per-site watcher invalidates the route-table cache and compiled bundles within ~1-2s of any file change under those directories — no redeploy needed for edits to existing routes.

[build]
watch_dirs = ["src/app", "src/components", "src/lib"]
live_reload = true

Gotchas that need a purge-site

Two changes are not covered by the watcher and need the purge-site call from step 3:

  • A brand-new site or route. Adding a new site — or a new page.tsx / route.ts — needs the route table evicted.
  • A new HTTP method on an existing route.ts. Adding export function DELETE to a route.ts that previously only exported GET returns 405 Method Not Allowed until you purge — the per-method handler set is a separate cache.
Note

public/islands/* is intentionally not watched. Cache-bust island scripts by bumping a ?v= query param on the <script src> instead.

Related