Configuration
Everything a storefront reads from the environment, and how it decides which store to serve.
Environment variables
Required
| Variable | What it is |
|---|---|
FLIGHTDECK_API_URL | The commerce API origin, e.g. https://api.ruo.pro. |
FLIGHTDECK_TENANT | Your store’s tenant ref. Pins this deployment to one store (see Resolution modes). |
FLIGHTDECK_STOREFRONT_TOKEN | The x-storefront-token checkout credential. Server-side only — never shipped to the browser. |
SESSION_SECRET | Signs shopper account sessions. Use openssl rand -hex 32. Without it, sign-in degrades to guest checkout (checkout still works; order history does not). |
Optional
| Variable | Default | What it is |
|---|---|---|
NEXT_PUBLIC_ASSET_BASE_URL | platform asset host | CDN base for product/brand imagery. |
NEXT_PUBLIC_ASSET_VARIANTS | — | Comma list of available image variants. |
NEXT_PUBLIC_SENTRY_DSN | disabled | Client + server error reporting. |
NEXT_PUBLIC_SENTRY_ENV | — | Sentry environment label. |
Local-dev only
| Variable | Effect |
|---|---|
ALLOW_FIXTURE_MODE=1 | Permits the bundled-fixture fallback when FLIGHTDECK_API_URL is unset. Refused in production. |
Anything prefixed
NEXT_PUBLIC_is inlined into the browser bundle by design and is not secret. The only secrets here areFLIGHTDECK_STOREFRONT_TOKENandSESSION_SECRET.
Resolution modes
Every request must resolve to exactly one store. There are two ways it can, and
which one runs depends on whether FLIGHTDECK_TENANT is set.
Env-pinned single-tenant (headless) — FLIGHTDECK_TENANT set
This deployment is one store. The manifest is resolved directly by tenant
against the public site contract
(GET {FLIGHTDECK_API_URL}/v1/tenants/{tenant}/site), and the request Host
header is ignored entirely. That route returns the active manifest for a
live store ({ tenant_ref, version, manifest }) and answers a conditional
GET with 304 — see Site builder.
This is the mode you want for a bring-your-own-Vercel store, because it means:
- The store renders on the ephemeral
*.vercel.apppreview URL. - It renders before you’ve verified a custom domain.
- A preview deployment and production serve the same store.
Host-resolved multi-tenant — FLIGHTDECK_TENANT unset
The store is resolved from the incoming Host header against your verified
domain mappings, and the resolved manifest is read against the same public site
contract. An unknown or unverified host is a real 404 — no fallback store, no
default tenant. This is the mode the platform’s own multi-tenant hosted surface
runs in (it maps Host to a tenant_ref internally, then reads
/v1/tenants/{tenant}/site); you generally don’t need it for a single store,
and there is no public hostname-keyed endpoint you call directly.
Honest failure
Store resolution is fail-closed and never launders an error into an empty store:
- Unknown tenant / unverified host -> a genuine 404 (the store is “not found”, which your app should render as unavailable — not as an empty store).
- A transport hiccup -> the last-good manifest is served from cache, and the failure is logged. You never get a blank store because a single fetch flaked.
Fixture mode (local only)
With FLIGHTDECK_API_URL unset, the starter serves bundled demo manifests +
catalog so you can do UI work with no running platform. This is refused in
production unless ALLOW_FIXTURE_MODE=1 is explicitly set — a production env
misconfiguration can never silently serve a demo catalog under a live domain.