betavoidbase is in public beta. It runs, the API is PocketBase's and is not moving, and the version is still 0.x for everything around that.Help us get it to 1.0

vb_secrets

A stack app has three audiences for its configuration: the server, the build, and the browser. One declaration covers all three, and each key says which of them may read it.

The declaration

main.ts belongs in the repository. secrets.json beside it holds the values on your machine and must be git-ignored.

// vb_secrets/main.ts
import { defineSecrets, secret, server, browser, local, string, number, boolean } from "@voidbase-cloud/voidbase/secrets";

export default defineSecrets({
  STRIPE_SECRET_KEY: secret(string(), "server side only, never in a build"),

  MAX_UPLOAD_MB:     server(number().default(10)),
  FEATURE_COMMENTS:  server(boolean().default(true)),

  PUBLIC_SITE_NAME:  browser(string().default("My App")),
  PUBLIC_STRIPE_KEY: browser(string()),

  VOIDBASE_DEPLOY_CF_API_KEY: local(string(), "the deploy token"),
  VOIDBASE_DEPLOY_NAME:       local(string().default("my-app"), "the Worker this deploys to"),
});

The four audiences

WrapperWho sees the value
secret()The deployed Worker only, encrypted. Never in a build, never listed back.
server()Routes, middleware, crons, queues and hooks. A plain variable on the Worker.
browser()The same, and inlined into the client bundle, so anyone who loads the page can read it.
local()Your machine and your CI: the deploy token, the Worker's name. Never deployed.

Every key must be wrapped in one of them; a bare validator is refused at build time. That is the whole point of the file: the person maintaining it is the one deciding what reaches a browser, so it makes them say so rather than letting a naming convention decide.

Reading them

In the client, a browser key is inlined by the build, so it is a constant by the time the page runs:

// in a page or a component: the value is inlined at build time
const name = import.meta.env.PUBLIC_SITE_NAME;

On the server, in a route or a hook, it is the environment:

// in a route or a hook
const limit = Number($os.getenv("MAX_UPLOAD_MB"));

A browser() key is public the moment you deploy. Anything that would embarrass you in view source belongs in secret(), and a build that inlines it will not tell you afterwards.

Seeing the state of it

voidbase secrets, run inside the generated .voidbase/, lists every declared key, its audience, whether it has a value here or a default, and whether the Worker already has it. Everything on a project's pb_secrets page applies: the same validators, the same defaults, the same refusal to deploy an invalid or missing value, and the same rule that a deploy stores a secret the Worker lacks but never replaces one it has.

The adapter copies this declaration into the generated instance on build, so the deployed Worker validates against the same file you edited.

Found something wrong on this page?

Fix it yourself. The link below opens this file in GitHub's editor and forks the repository for you if you need one, and your change becomes a pull request without leaving the browser.