Configuration
Where variables and secrets live, locally and in production, and how code reads them.
Configuration comes from three places: bindings and variables in wrangler.jsonc, secrets stored on the Worker, and Astro's typed env schema.
Variables
Values that aren't secret go in vars in wrangler.jsonc:
Variable | What it does |
|---|---|
| The site's real origin. Better Auth and Stripe redirects are built from it |
| The default sender for |
PUBLIC_URL is also read at build time. The deploy script in package.json builds with it set, so change it in both places.
Secrets
Secret | Required | What it does |
|---|---|---|
| Yes | Signs sessions. Use a long random string |
| For payments | Your Stripe secret key |
| For payments | The webhook's signing secret |
| No |
|
Provider key | With | For example |
Locally, put them in .dev.vars; copy .dev.vars.example to start. It's gitignored. In production, set each one on the Worker:
bunx wrangler secret put BETTER_AUTH_SECRETReading configuration in code
Bindings and wrangler.jsonc variables come from the Worker environment:
import { env } from 'cloudflare:workers';
const origin = env.PUBLIC_URL;Values the app reads through astro:env must be declared in the env.schema block in astro.config.mjs, where each one is marked client or server, and public or secret:
import { getSecret } from 'astro:env/server';
const provider = getSecret('EMAIL_PROVIDER');Astro validates the schema at build and start-up, so a missing required value fails early with a clear error. Never import a secret into client code.
After editing wrangler.jsonc
Run bun run cf-typegen to regenerate worker-configuration.d.ts, so env has the right types.