Skip to content

Storefront visibility

A deploy is not the same as a launch. Between the two, Stripe gets connected, SMTP gets a real sender, shipping zones get argued about, all of which need a deployed store since webhooks cannot reach localhost, while the catalogue is still three placeholder products on a test key. Settings → Visibility puts a password on the storefront for exactly that stretch: public or password, defaulting to public so every existing store comes through the migration as open as it was.

Beluga already has one: the Stripe secret key, sk_test_ or sk_live_. A database-backed mode beside it would be a second source of truth for the same question, with the interesting states being the contradictions. What the key cannot express is who is allowed to look, which is what this adds.

The gate is positional. The Stripe webhook, the health check, the admin sign-in and setup APIs, the crawler files and the built client bundle are mounted above it and so are exempt by construction; the storefront API, checkout, shipping, cart and uploaded imagery are mounted below it and gated by the same construction. An administrator’s own session always passes.

Locked, robots.txt disallows everything with no Sitemap: line, sitemap.xml is 404, and an anonymous GET /product/<slug> carries no product name, price, image or JSON-LD in its <head>, because the production HTML handler skips the metadata for that request entirely rather than trusting it to omit the sensitive fields.

A shared password is a bad thing to send a client, so what gets sent is a link. POST /api/admin/storefront/share-link mints a token and returns the full URL exactly once, the same handling as a webhook signing secret. The client posts the token to POST /api/storefront/unlock and strips it from the URL immediately, which keeps it out of every access log between here and there.

Changing the password or rotating the share link bumps a version number; a session’s grant is only honoured while it matches, which is what makes revocation real against a 24-hour rolling cookie. Every existing viewer is out on their next request, and the admin session is unaffected.

Visibility carries the checklist behind Open the store: Stripe connected, a live key, webhooks connected, the public URL not localhost, shipping rates that cover where the store ships, an email provider, and something live to buy. Nothing on it blocks the switch, but flipping to public with rows still failing asks for confirmation first and names what is outstanding. The one state that gets a persistent error-level notice is public and holding a test key: checkout completes, the buyer sees a confirmation, and no money moved.

Go live is the walkthrough.