> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibestrap.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> Every env var the scaffold reads, what it does, and whether you can skip it.

The scaffold validates env vars at startup with [@t3-oss/env-nextjs](https://env.t3.gg)
and Zod. The full schema lives in `src/env.ts` — open it for the source of truth.
This page mirrors that file, organized by category, so you can copy-paste your way
to a working `.env.local` (and prod env) in one pass.

A few conventions:

* **Required** vars throw at startup if missing or empty.
* **Optional** vars default to empty string and the consuming module no-ops gracefully.
* `NEXT_PUBLIC_*` vars are **shipped to the browser**. Never put secrets in them.
* Set `SKIP_ENV_VALIDATION=true` to bypass validation in CI build steps that don't
  need real values (Vercel preview builds, Docker image bakes, etc.).

## Core

The bare minimum for the app to boot.

| Variable               | Required | Default                 | Description                                                                              |
| ---------------------- | -------- | ----------------------- | ---------------------------------------------------------------------------------------- |
| `NODE_ENV`             | no       | `development`           | `development` / `production` / `test`. Set automatically by your runtime.                |
| `DATABASE_PROVIDER`    | no       | `postgres`              | Reserved for future drivers. Only `postgres` is supported today.                         |
| `DATABASE_URL`         | **yes**  | —                       | Postgres connection string. Use the **pooled** URL in production.                        |
| `BETTER_AUTH_SECRET`   | **yes**  | —                       | 16+ char secret for session signing. Generate: `openssl rand -base64 32`.                |
| `BETTER_AUTH_URL`      | no       | —                       | Full URL (with scheme) of your deployed app. Required in production for OAuth callbacks. |
| `NEXT_PUBLIC_APP_URL`  | no       | `http://localhost:3000` | Used by sitemap, OG images, OAuth redirects. Set to your prod URL.                       |
| `NEXT_PUBLIC_APP_NAME` | no       | `Vibestrap`             | Display name in titles, OG metadata, emails.                                             |
| `ADMIN_EMAILS`         | no       | `''`                    | Comma-separated list of admin emails. Auto-promoted to `role: 'admin'` on signup.        |

## OAuth

Each provider is independent — set both id + secret to enable, leave blank to hide.

| Variable                       | Required | Default | Description                                                                   |
| ------------------------------ | -------- | ------- | ----------------------------------------------------------------------------- |
| `GOOGLE_CLIENT_ID`             | no       | `''`    | Google OAuth client id. Enables "Sign in with Google".                        |
| `GOOGLE_CLIENT_SECRET`         | no       | `''`    | Google OAuth secret (server-only).                                            |
| `NEXT_PUBLIC_GOOGLE_CLIENT_ID` | no       | `''`    | Mirror of `GOOGLE_CLIENT_ID`. Needed for client-side One-Tap. Safe to expose. |
| `GITHUB_CLIENT_ID`             | no       | `''`    | GitHub OAuth app id. Enables "Sign in with GitHub".                           |
| `GITHUB_CLIENT_SECRET`         | no       | `''`    | GitHub OAuth secret.                                                          |

## Mail

Resend is the default. The mail facade no-ops gracefully if `RESEND_API_KEY` is empty.

| Variable                | Required | Default                 | Description                                                                     |
| ----------------------- | -------- | ----------------------- | ------------------------------------------------------------------------------- |
| `RESEND_API_KEY`        | no       | `''`                    | Resend API key (`re_…`). Powers verification + welcome + reset-password emails. |
| `RESEND_FROM_EMAIL`     | no       | `onboarding@resend.dev` | `From:` address. Switch to your verified domain in production.                  |
| `RESEND_REPLY_TO_EMAIL` | no       | `''`                    | Optional `Reply-To:` header.                                                    |
| `RESEND_AUDIENCE_ID`    | no       | `''`                    | Resend Audience id for newsletter (when `newsletter.provider = 'resend'`).      |

## Newsletter — Beehiiv

Only used if `siteConfig.newsletter.provider = 'beehiiv'`.

| Variable                 | Required | Default | Description               |
| ------------------------ | -------- | ------- | ------------------------- |
| `BEEHIIV_API_KEY`        | no       | `''`    | Beehiiv v2 API key.       |
| `BEEHIIV_PUBLICATION_ID` | no       | `''`    | Publication id (`pub_…`). |

## Payments — Stripe

Default provider. Only the `*_PRICE_*` ids you actually sell need to be set.

| Variable                             | Required        | Default | Description                                         |
| ------------------------------------ | --------------- | ------- | --------------------------------------------------- |
| `STRIPE_SECRET_KEY`                  | yes (if active) | `''`    | `sk_test_…` / `sk_live_…`.                          |
| `STRIPE_WEBHOOK_SECRET`              | yes (if active) | `''`    | `whsec_…` from the Stripe dashboard webhook config. |
| `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | no              | `''`    | `pk_…`. Needed for Stripe.js / Elements.            |
| `STRIPE_PRICE_VIBESTRAP_PROMO`       | no              | `''`    | Price id for the Vibestrap promo tier (\$49).       |
| `STRIPE_PRICE_VIBESTRAP_STANDARD`    | no              | `''`    | Price id for the Vibestrap standard tier (\$99).    |
| `STRIPE_PRICE_PRO_MONTHLY`           | no              | `''`    | Demo Pro plan, monthly recurring.                   |
| `STRIPE_PRICE_PRO_YEARLY`            | no              | `''`    | Demo Pro plan, yearly recurring.                    |

## Payments — Creem

Only used if `siteConfig.payment.provider = 'creem'`.

| Variable                         | Required        | Default | Description                 |
| -------------------------------- | --------------- | ------- | --------------------------- |
| `CREEM_API_KEY`                  | yes (if active) | `''`    | Creem API key.              |
| `CREEM_WEBHOOK_SECRET`           | yes (if active) | `''`    | Webhook signing secret.     |
| `CREEM_PRICE_VIBESTRAP_PROMO`    | no              | `''`    | Price id for promo tier.    |
| `CREEM_PRICE_VIBESTRAP_STANDARD` | no              | `''`    | Price id for standard tier. |

## AI providers

Set `AI_PROVIDER` to switch between providers. The `mock` provider streams fake
tokens without keys, so demo pages run offline out of the box.

| Variable              | Required | Default                        | Description                                                           |
| --------------------- | -------- | ------------------------------ | --------------------------------------------------------------------- |
| `AI_PROVIDER`         | no       | `mock`                         | `mock` / `openrouter` / `openai` / `anthropic` / `replicate` / `fal`. |
| `OPENROUTER_API_KEY`  | no       | `''`                           | OpenRouter key (gateway to most LLMs).                                |
| `OPENROUTER_BASE_URL` | no       | `https://openrouter.ai/api/v1` | Override only if self-hosting a gateway.                              |
| `OPENAI_API_KEY`      | no       | `''`                           | OpenAI key (`sk-…`).                                                  |
| `OPENAI_BASE_URL`     | no       | `https://api.openai.com/v1`    | Override for Azure OpenAI or compat endpoints.                        |
| `ANTHROPIC_API_KEY`   | no       | `''`                           | Anthropic key (`sk-ant-…`).                                           |
| `ANTHROPIC_BASE_URL`  | no       | `https://api.anthropic.com`    | Override for Bedrock / proxy.                                         |
| `REPLICATE_API_TOKEN` | no       | `''`                           | Replicate API token for image / audio models.                         |
| `FAL_KEY`             | no       | `''`                           | fal.ai key for fast image generation.                                 |

## Storage (S3 / R2)

Stub by default — wire only if you need uploads or signed downloads.

| Variable               | Required | Default | Description                                          |
| ---------------------- | -------- | ------- | ---------------------------------------------------- |
| `S3_ENDPOINT`          | no       | `''`    | Endpoint URL. AWS S3, Cloudflare R2, MinIO all work. |
| `S3_REGION`            | no       | `''`    | Bucket region. R2 uses `auto`.                       |
| `S3_ACCESS_KEY_ID`     | no       | `''`    | Access key id.                                       |
| `S3_SECRET_ACCESS_KEY` | no       | `''`    | Secret access key.                                   |
| `S3_BUCKET`            | no       | `''`    | Bucket name.                                         |
| `S3_PUBLIC_URL`        | no       | `''`    | Public CDN base URL for served objects.              |

## Anti-bot — Cloudflare Turnstile

Set both keys to enable Turnstile on signup, forgot-password, and newsletter forms.

| Variable                         | Required | Default | Description                      |
| -------------------------------- | -------- | ------- | -------------------------------- |
| `TURNSTILE_SECRET_KEY`           | no       | `''`    | Server-side verification secret. |
| `NEXT_PUBLIC_TURNSTILE_SITE_KEY` | no       | `''`    | Public site key for the widget.  |

## Customer service

One widget at a time, picked by `siteConfig.customerService.provider`. Each widget
self-gates on its env vars.

| Variable                             | Required | Default                    | Description                                   |
| ------------------------------------ | -------- | -------------------------- | --------------------------------------------- |
| `NEXT_PUBLIC_CRISP_WEBSITE_ID`       | no       | `''`                       | Crisp website id (UUID).                      |
| `NEXT_PUBLIC_TAWK_PROPERTY_ID`       | no       | `''`                       | tawk.to property id.                          |
| `NEXT_PUBLIC_TAWK_WIDGET_ID`         | no       | `''`                       | tawk.to widget id.                            |
| `NEXT_PUBLIC_INTERCOM_APP_ID`        | no       | `''`                       | Intercom workspace id.                        |
| `NEXT_PUBLIC_CHATWOOT_WEBSITE_TOKEN` | no       | `''`                       | Chatwoot website token.                       |
| `NEXT_PUBLIC_CHATWOOT_BASE_URL`      | no       | `https://app.chatwoot.com` | Self-hosted Chatwoot URL if you run your own. |

## Affiliate

Set the matching var(s) for whichever provider is active in `siteConfig.affiliate.provider`.
The `internal` provider needs no env vars.

| Variable                         | Required | Default | Description               |
| -------------------------------- | -------- | ------- | ------------------------- |
| `NEXT_PUBLIC_AFFONSO_PROGRAM_ID` | no       | `''`    | Affonso program id.       |
| `NEXT_PUBLIC_REWARDFUL_API_KEY`  | no       | `''`    | Rewardful public API key. |

## Analytics

Each script renders only when its env var is set. Mix and match freely.

| Variable                          | Required | Default                    | Description                                               |
| --------------------------------- | -------- | -------------------------- | --------------------------------------------------------- |
| `NEXT_PUBLIC_GOOGLE_ANALYTICS_ID` | no       | `''`                       | GA4 measurement id (`G-…`).                               |
| `NEXT_PUBLIC_POSTHOG_KEY`         | no       | `''`                       | PostHog project key.                                      |
| `NEXT_PUBLIC_POSTHOG_HOST`        | no       | `https://us.i.posthog.com` | EU users: `https://eu.i.posthog.com`.                     |
| `NEXT_PUBLIC_PLAUSIBLE_DOMAIN`    | no       | `''`                       | Plausible site domain.                                    |
| `NEXT_PUBLIC_PLAUSIBLE_HOST`      | no       | `https://plausible.io`     | Self-hosted Plausible URL if applicable.                  |
| `NEXT_PUBLIC_UMAMI_WEBSITE_ID`    | no       | `''`                       | Umami website id.                                         |
| `NEXT_PUBLIC_UMAMI_HOST`          | no       | `https://cloud.umami.is`   | Self-hosted Umami URL if applicable.                      |
| `NEXT_PUBLIC_CLARITY_PROJECT_ID`  | no       | `''`                       | Microsoft Clarity project id (heatmaps + session replay). |

## Search-engine site verification

Each emits a `<meta>` tag in `<head>` via Next.js `metadata.verification`,
proving ownership in the matching webmaster console. Server-side env vars (no
`NEXT_PUBLIC_` prefix). Empty values render no tag.

| Variable                   | Required | Default | Description                                                                         |
| -------------------------- | -------- | ------- | ----------------------------------------------------------------------------------- |
| `GOOGLE_SITE_VERIFICATION` | no       | `''`    | Google Search Console — `content` value of the `google-site-verification` meta tag. |
| `BING_SITE_VERIFICATION`   | no       | `''`    | Bing Webmaster Tools — `content` value of the `msvalidate.01` meta tag.             |
| `YANDEX_SITE_VERIFICATION` | no       | `''`    | Yandex Webmaster — `content` value of the `yandex-verification` meta tag.           |

## GitHub invite delivery

Token used by the buyer flow to add a paid customer as a read-only collaborator
on your private source repo. See [GitHub invite delivery](/operations/github-invite-delivery)
for the full setup.

| Variable              | Required | Default | Description                                                                                                       |
| --------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
| `GITHUB_INVITE_TOKEN` | no       | `''`    | Fine-grained PAT scoped to one repo with Metadata:read + Administration:write. Empty = invite UI disables itself. |

## Misc

| Variable                | Required | Default | Description                                                                 |
| ----------------------- | -------- | ------- | --------------------------------------------------------------------------- |
| `NEXT_PUBLIC_DEMO_MODE` | no       | `false` | Set `true` to hide real payment + auth and show the read-only demo overlay. |

## See also

* [Vercel deployment](/deployment/vercel) — where to paste these in production.
* [Cloudflare deployment](/deployment/cloudflare) — `wrangler secret put` for each secret.
* [Configuration](/configuration) — `siteConfig` toggles that switch which providers read which keys.
