Getting Started
Environment variables
Every environment variable the template reads, grouped and explained.
Environment variables carry two things: secrets (database URL, API keys) and deploy identity (canonical URL, metadata defaults baked into pages at build time). Everything a visitor sees — site name, colors, prices — lives in /admin/settings instead. That two-layer rule is covered in Configuration.
Only DATABASE_URL and BETTER_AUTH_SECRET are truly required. Every other variable is optional, and the feature it powers simply stays off until you provide it. The canonical source is .env.example in the repo root; this page annotates it.
Core
| Variable | Required | What it is |
|---|---|---|
DATABASE_URL | Yes | Postgres connection string. Used by the app, migrations, and the seed. |
NEXT_PUBLIC_SITE_URL | In production | Canonical site URL. Drives sitemaps, canonicals, and OG defaults. |
BETTER_AUTH_SECRET | Yes | Signing secret for auth sessions. Generate with openssl rand -base64 32. |
BETTER_AUTH_URL | Recommended | Base URL auth callbacks resolve against; set to your site URL in production. |
Build-time identity
Baked into page metadata at build time. These are SEO defaults, not the displayed identity — the visible name and links live in /admin/settings.
| Variable | Required | What it is |
|---|---|---|
NEXT_PUBLIC_SITE_NAME | No | Default site name in metadata before settings load. |
NEXT_PUBLIC_SITE_TWITTER | No | Twitter/X handle for Twitter card metadata. |
NEXT_PUBLIC_SITE_AUTHOR | No | Author name in structured data. |
NEXT_PUBLIC_SITE_AUTHOR_URL | No | Author URL in structured data. |
NEXT_PUBLIC_SITE_SAME_AS | No | Comma-separated profile URLs for sameAs JSON-LD (social proof). |
Agent access
| Variable | Required | What it is |
|---|---|---|
AWP_API_KEY | No | Bootstrap API key for pipelines and agents to use before you create scoped keys in /admin/api-keys. Convenient for first setup; prefer scoped keys once the site is running. |
AI editorial (DeepSeek)
Powers news digests, tool enrichment, comparisons, stacks, roles, and tags. Without a key, those pipelines skip their editorial step and the site works as a manually curated directory. These can instead be set at /admin/settings → Integrations, which takes precedence for day-to-day use.
| Variable | Required | What it is |
|---|---|---|
DEEPSEEK_API_KEY | No | DeepSeek API key. Enables all AI editorial. |
DEEPSEEK_MODEL | No | Model name. Default deepseek-chat. |
DEEPSEEK_BASE_URL | No | API base URL. Default https://api.deepseek.com. |
Storage (Cloudflare R2)
Stores tool logos and screenshots. Optional — without it, image capture is skipped and the site falls back to remote or placeholder images. Also settable in the admin console.
| Variable | Required | What it is |
|---|---|---|
R2_ACCOUNT_ID | No | Cloudflare account ID. |
R2_ACCESS_KEY_ID | No | R2 access key ID. |
R2_SECRET_ACCESS_KEY | No | R2 secret access key. |
R2_BUCKET | No | Bucket name for uploads. |
R2_PUBLIC_URL | No | Public base URL the bucket is served from. |
Payments (Stripe)
Enables built-in monetization — paid fast-track reviews and featured placements. Without these, the paid options simply don't appear. Full setup in Monetization.
| Variable | Required | What it is |
|---|---|---|
STRIPE_SECRET_KEY | No | Stripe secret key. Turns on the paid checkout flows. |
STRIPE_WEBHOOK_SECRET | No | Signing secret for the /api/webhooks/stripe endpoint that fulfills orders. |
The two-layer rule
Keep deploy identity and secrets in env, and display identity and prices in /admin/settings. The canonical URL is the one deliberate overlap: NEXT_PUBLIC_SITE_URL always wins over any database value, so canonicals stay stable across deploys. Everything else visible on the page comes from settings, which is why a fresh clone renders correctly before you've entered anything — every setting has a hardcoded fallback.