import { Aside } from ‘@astrojs/starlight/components’;
App Configuration
| Variable | Required | Description |
|---|
NEXT_PUBLIC_APP_URL | ✓ | Canonical URL — https://brettjohnson.xyz |
NEXT_PUBLIC_APP_ENV | ✓ | production | staging | development |
Supabase
| Variable | Required | Description |
|---|
NEXT_PUBLIC_SUPABASE_URL | ✓ | Supabase project URL (public) |
NEXT_PUBLIC_SUPABASE_ANON_KEY | ✓ | Supabase anon key (public, RLS enforced) |
SUPABASE_SERVICE_ROLE_KEY | ✓ | Service role key — server-side only |
DATABASE_URL | migrations only | Direct PostgreSQL connection string |
Email (Resend)
| Variable | Required | Description |
|---|
RESEND_API_KEY | ✓ | Resend API key |
EMAIL_FROM | ✓ | Sender address — hello@brettjohnson.xyz |
EMAIL_INTERNAL_NOTIFY | ✓ | Internal notification recipient |
HubSpot CRM
| Variable | Required | Description |
|---|
HUBSPOT_PRIVATE_APP_TOKEN | ✓ | HubSpot private app access token |
HUBSPOT_PIPELINE_ID | ✓ | Booking pipeline ID |
HUBSPOT_STAGE_NEW | ✓ | Deal stage ID for “New Inquiry” |
Cloudflare Turnstile
| Variable | Required | Description |
|---|
NEXT_PUBLIC_TURNSTILE_SITE_KEY | ✓ | Site key (public) |
TURNSTILE_SECRET_KEY | ✓ | Secret key — server-side only |
Cloudflare R2
| Variable | Required | Description |
|---|
CF_R2_ACCOUNT_ID | ✓ | Cloudflare account ID |
CF_R2_ACCESS_KEY_ID | ✓ | R2 access key ID |
CF_R2_SECRET_ACCESS_KEY | ✓ | R2 secret — server-side only |
CF_R2_BUCKET_NAME | ✓ | Bucket name — brettjohnson-media |
NEXT_PUBLIC_MEDIA_BASE_URL | ✓ | CDN URL — https://media.brettjohnson.xyz |
Upstash Redis
| Variable | Required | Description |
|---|
UPSTASH_REDIS_REST_URL | ✓ | Redis REST API URL |
UPSTASH_REDIS_REST_TOKEN | ✓ | Redis REST token — server-side only |
Calendly
| Variable | Required | Description |
|---|
NEXT_PUBLIC_CALENDLY_URL | ✓ | Calendly event type embed URL |
Analytics & Monitoring
| Variable | Required | Description |
|---|
NEXT_PUBLIC_PLAUSIBLE_DOMAIN | ✗ | Plausible domain — brettjohnson.xyz |
NEXT_PUBLIC_SENTRY_DSN | ✗ | Sentry DSN |
SENTRY_AUTH_TOKEN | CI only | Source map upload token |
SENTRY_ORG | CI only | Sentry organization slug |
SENTRY_PROJECT | CI only | Sentry project slug |
Feature Flags
| Variable | Default | Description |
|---|
NEXT_PUBLIC_FEATURE_PODCAST | false | Enable podcast section |
NEXT_PUBLIC_FEATURE_MEDIA_KIT | false | Enable media kit download |
NEXT_PUBLIC_FEATURE_CALENDLY | false | Enable Calendly embed |
NEXT_PUBLIC_FEATURE_HUBSPOT_SYNC | false | Enable HubSpot CRM sync |
NEXT_PUBLIC_FEATURE_PLAUSIBLE | false | Enable Plausible analytics |
NEXT_PUBLIC_FEATURE_SENTRY | false | Enable Sentry error tracking |
CI/CD (GitHub Actions Secrets)
Set in GitHub → Settings → Secrets and variables → Actions.
| Secret | Description |
|---|
VERCEL_TOKEN | Vercel API token |
VERCEL_ORG_ID | Vercel team ID |
VERCEL_PROJECT_ID_WWW | Project ID for apps/www |
VERCEL_PROJECT_ID_API | Project ID for apps/api |
VERCEL_PROJECT_ID_DOCS | Project ID for apps/docs |
SENTRY_AUTH_TOKEN | Sentry source map token |
SNYK_TOKEN | Snyk dependency scanning |
Environment Matrix
| Category | Development | Staging | Production |
|---|
| App URL | http://localhost:3000 | https://staging.brettjohnson.xyz | https://brettjohnson.xyz |
| Supabase | Dev project | Staging project | Prod project |
| Resend | Test mode | Live (test recipient) | Live |
| Turnstile | Test keys (always pass) | Live keys | Live keys |
| Feature flags | All true | All true | Staged rollout |
Secret Rotation Policy
| Trigger | Action |
|---|
| Engineer offboarding | Rotate all secrets immediately |
| Accidental commit | Rotate within 15 min + audit access logs |
| Vendor security incident | Rotate affected vendor credentials |
| Scheduled | All secrets reviewed quarterly |