Docs
Environment and Configuration
A purpose-only reference to every Seedly Communities setting - what each value is for, where it goes, and which ones are required to run.
Last updated
Every operator-facing setting a live instance cares about, grouped by area. This page explains what each value is for, never the value itself. The example environment file in your download lists the same names with blanks to fill in, and it is generated from the platform's own manifest so it always matches your version.
There are three kinds of value.
- generated - the platform's own secrets, minted for you by
npx pnpm run gen:secrets - provider - a key or token you get from a third party (Stripe, your email provider, Daily.co, Vercel, and so on)
- config - a plain value you choose, like your domain
Where they go. A value lives on the half of the platform that reads it. Some go in your local environment file, some go on the backend deployment (set with npx convex env set for development and npx convex env set --prod for production), and some go on the web app project in Vercel. Several go in more than one place, and each entry below says where. In a local run most optional values are unset and the platform falls back to safe behavior.
The authoritative check is the doctor. Run npx pnpm run setup:check for a local instance, or npx pnpm run setup:check -- --target=prod for a live one, and it names exactly what is missing. Keep every secret in a password manager and never commit one to Git.
Backend Connection#
Wires the running app to the Convex Cloud backend.
| Name | Kind | Required | Purpose |
|---|---|---|---|
CONVEX_DEPLOYMENT | config | yes | Anchors the command line tool to your project so deploy commands target the right backend. Set locally |
NEXT_PUBLIC_CONVEX_URL | config | yes | The backend URL the running app connects to. Development URL locally, production URL on Vercel |
NEXT_PUBLIC_CONVEX_SITE_URL | config | yes | The browser-readable backend site origin used by the custom-domain redirect and server auth helpers |
App#
Tells the platform where it lives.
| Name | Kind | Required | Purpose |
|---|---|---|---|
SITE_URL | config | yes | The app's public origin. Sign-in cookies, email links, and redirect safety all key off it, so it must match your real domain in production. The single most important "where am I" value |
NEXT_PUBLIC_SITE_URL | config | no | A browser-readable fallback read only by the in-app custom-domain admin page. Setting SITE_URL alone is enough for normal use |
COMMUNITY_NAME | config | no | A legacy fallback for the community name. The live name comes from the admin Settings page, so this is safe to leave unset |
Auth and Secrets#
Signs sessions and protects abuse controls. These are per-environment. Never share one value between development and production, and do not rotate them on a live deployment or existing signed and protected data stops matching.
| Name | Kind | Required | Purpose |
|---|---|---|---|
BETTER_AUTH_SECRET | generated | yes | Signs sign-in sessions and tokens. Lives on the backend deployment. Distinct per environment |
ENCRYPTION_KEY | generated | yes | Protects the identifiers behind abuse detection and rate limiting. Read by both halves, so it goes on the backend, on Vercel, and in your local file, sharing one value within each environment. Distinct per environment |
AUTH_PROXY_SECRET | config | no | Optional but strongly recommended (v2.2.0+). A shared secret your web app attaches when it passes sign-in, sign-up, and password-reset requests to the backend. With it set, anyone who calls your backend directly to skip your sign-in protection is refused, and the sign-in rate limit works per visitor IP. Without it, sign-in still works and is still protected, with the rate limit counted per email. Generate it with openssl rand -hex 32 and use the same value on Vercel and on the matching backend. Order matters: add it on Vercel and redeploy the website first, then set it on the backend. The reverse order refuses every sign-in until the website redeploy finishes |
GOOGLE_CLIENT_ID | provider | no | The Google sign-in client id. Unset means Google sign-in is simply off |
GOOGLE_CLIENT_SECRET | provider | no | The Google sign-in client secret, paired with the id above |
Email#
Delivers sign-in, notifications, and digests. See Email and Deliverability for the full walkthrough. These read on the backend.
| Name | Kind | Required | Purpose |
|---|---|---|---|
EMAIL_PROVIDER | config | yes | Chooses your email provider. Pick one and set its key below |
EMAIL_FROM | config | yes | The From address for all outbound email. Must be a verified sender at your provider. If unset, verification and password-reset emails fail closed rather than send from a bogus address |
SENDGRID_API_KEY | provider | when selected | Transport key, required when your provider is SendGrid (the default) |
POSTMARK_SERVER_TOKEN | provider | when selected | Transport token, required when your provider is Postmark |
EMAIL_PROVIDER_TRANSACTIONAL | config | no | An optional separate provider for auth emails, on a dedicated sending stream for better inbox placement. Falls back to EMAIL_PROVIDER when unset |
SENDGRID_API_KEY_TRANSACTIONAL | provider | no | A dedicated SendGrid key for the separate auth-email stream |
POSTMARK_SERVER_TOKEN_TRANSACTIONAL | provider | no | A dedicated Postmark token for the separate auth-email stream |
Payments (Stripe)#
Runs paid tiers, courses, and coaching through your own Stripe account. Required only if you sell access. See Payments and Stripe Setup. These read on the backend.
| Name | Kind | Required | Purpose |
|---|---|---|---|
STRIPE_SECRET_KEY | provider | for paid | Your Stripe API key. Use the test key on the development backend and the live key on production. Never mix the two |
STRIPE_WEBHOOK_SECRET | provider | for paid | Verifies that payment webhook events genuinely came from Stripe. Each endpoint, test and live, has its own value, so match it to the environment |
Live Video (Daily.co)#
Powers live events, meetings, and recordings through a third-party real-time video provider. Since v2.2.0, recordings stay in your Daily.co account and play in your community from there. Optional. Unset means the live streaming module stays inactive. See Live Video Setup. These read on the backend.
| Name | Kind | Required | Purpose |
|---|---|---|---|
DAILY_API_KEY | provider | for live | Your Daily.co API key. Unset means live events are off |
DAILY_WEBHOOK_SECRET | generated | no | Verifies the recording-ready callbacks from Daily.co. Register the same value on the Daily.co webhook. Distinct per environment |
Slide Storage (Vercel Blob)#
Since v2.2.0, live recordings are no longer copied here. They stay in your Daily.co account, so deleting a recording in Daily removes it from your community. Recordings copied before v2.2.0 keep playing from this storage.
| Name | Kind | Required | Purpose |
|---|---|---|---|
BLOB_READ_WRITE_TOKEN | provider | no | The storage token the backend uses when a host uploads a slide deck to present in a live session. Vercel sets it on the web app project automatically, but you must copy it to the production backend by hand |
AI (Optional)#
Powers the optional AI helpers. Both are off when unset.
| Name | Kind | Required | Purpose |
|---|---|---|---|
ANTHROPIC_API_KEY | provider | no | Enables the AI assistant and content summaries |
ANTHROPIC_MODEL | provider | no | Overrides the assistant's default model. Leave unset unless you want a specific one (v2.1.1+) |
OPENAI_API_KEY | provider | no | Enables semantic search and knowledge-base embeddings |
Custom Domains (Optional)#
Powers the in-app admin page that attaches your own domain. Skip these and you can still attach a domain the normal way in the Vercel dashboard.
| Name | Kind | Required | Purpose |
|---|---|---|---|
VERCEL_TOKEN | provider | no | The Vercel API token the in-app custom-domain page uses |
VERCEL_PROJECT_ID | config | no | The Vercel project the custom-domain page manages |
VERCEL_TEAM_ID | config | no | Your Vercel team, if you use one. Skip on a personal account |
Mobile and Build#
| Name | Kind | Required | Purpose |
|---|---|---|---|
NEXT_PUBLIC_NATIVE_CALLS_ENABLED | config | no | One step of an opt-in for the native call path, which ships as disabled reference scaffolding. Setting the flag alone does nothing; enabling it also requires adding the native call package and a small code change described in that package's README |
ENABLE_EXPERIMENTAL_COREPACK | config | yes (Vercel) | Lets the package manager run during Vercel builds. Set it on the web app project |
Next Steps#
- Set the payment values on the backend, then walk Payments and Stripe Setup.
- Set the email values, then confirm delivery in Email and Deliverability.
- Set the video values, then finish Live Video Setup.
- Ready to go live? Return to Deploying to Production.
