Files
visit.waterschurch.org/.env.example
T
Waters ChurchandClaude Fable 5.1 78cd0cc550 Plan Your Visit landing page for visit.waterschurch.org
Next.js 16 static export + PHP 8 API for cPanel/Apache hosting.

- Location-aware campus finder (IP estimate, optional precise location, ZIP search)
- Three-step Plan Your Visit form with separate email/SMS consent
- PHP API: validation, anti-spam, rate limiting, SQLite lead store,
  Mailchimp and Sinch Engage adapters, idempotent retries via cron
- Attribution capture (utm_*, gclid/gbraid/wbraid, fbclid, ttclid, twclid) and
  consent-aware analytics hooks
- Vitest and PHP test suites, cPanel deployment script and docs

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 13:22:26 -04:00

111 lines
5.1 KiB
Bash

# =============================================================================
# visit.waterschurch.org — environment configuration (PLACEHOLDERS ONLY)
#
# Two consumers read this file format:
# 1. `npm run build` (Next.js) reads NEXT_PUBLIC_* from ./.env at build time.
# These values are embedded in the static HTML/JS — never put secrets here.
# 2. The PHP API reads EVERYTHING ELSE at runtime from
# <VISIT_PRIVATE_DIR>/.env on the server (outside the web root).
# Copy this file there as `.env` and fill in real values.
# =============================================================================
# ---- Public site ------------------------------------------------------------
NEXT_PUBLIC_SITE_URL=https://visit.waterschurch.org
PUBLIC_SITE_URL=https://visit.waterschurch.org
# Comma-separated extra origins allowed to call the API (local dev only)
ALLOWED_ORIGINS=http://localhost:3000,http://127.0.0.1:3000
# true = search engines may index. Set false on staging.
NEXT_PUBLIC_ROBOTS_INDEX=true
# Where the browser calls the API. Same-origin "/api" in production; php -S in dev.
NEXT_PUBLIC_API_BASE=/api
# Default landing-page variant label (override per ad with ?v=b)
NEXT_PUBLIC_VARIANT=a
# Legal pages
NEXT_PUBLIC_PRIVACY_URL=https://waterschurch.org/privacy/
NEXT_PUBLIC_TERMS_URL=
# "Text Us" number before a campus is chosen (must be SMS-enabled on the Sinch account)
NEXT_PUBLIC_CENTRAL_SMS_NUMBER=+15086951300
# ---- Integration mode -------------------------------------------------------
# mock = log what WOULD be sent, send nothing (default). live = real Mailchimp + Sinch calls.
INTEGRATION_MODE=mock
LOG_LEVEL=info
# Random string used to hash IPs for rate limiting / consent records. Generate: openssl rand -hex 32
HASH_SALT=change-me-to-a-long-random-string
# Set true ONLY if the site is behind Cloudflare or another trusted proxy
TRUST_PROXY_HEADERS=false
# ---- Lead storage -----------------------------------------------------------
# Default: SQLite at <VISIT_PRIVATE_DIR>/data/leads.sqlite (no setup needed).
# To use cPanel MySQL instead, create a database + user in cPanel and set:
DATABASE_DSN=
# e.g. mysql:host=localhost;dbname=cpaneluser_visit;charset=utf8mb4
DATABASE_USER=
DATABASE_PASSWORD=
# Override the data directory (must be writable by PHP and outside the web root)
DATA_DIR=
# Delete fully-processed leads older than N days (0 = keep forever). Confirm with Waters Church.
LEAD_RETENTION_DAYS=0
# ---- Mailchimp --------------------------------------------------------------
# Account → Extras → API keys. The key ends in "-usXX"; that suffix is the server prefix.
MAILCHIMP_API_KEY=
MAILCHIMP_SERVER_PREFIX=us21
# Audience → Settings → Audience name and defaults → "Audience ID"
MAILCHIMP_AUDIENCE_ID=
# Optional: API-triggered Customer Journey (Automations → journey → API trigger step)
MAILCHIMP_JOURNEY_ID=
MAILCHIMP_JOURNEY_STEP_ID=
# Tag prefix applied to every contact from this page
MAILCHIMP_TAG_PREFIX=Visit:
# true = new contacts start as "pending" and receive a Mailchimp confirmation email
MAILCHIMP_DOUBLE_OPTIN=false
# ---- Sinch Engage (formerly MessageMedia) -----------------------------------
# Sinch Engage portal → Settings → API credentials (Basic auth key + secret).
# Regional host: US https://us.app.api.sinch.com | EU https://eu.app.api.sinch.com | APAC https://au.app.api.sinch.com
SINCH_API_BASE=https://us.app.api.sinch.com
SINCH_API_KEY=
SINCH_API_SECRET=
# Send from each campus's own number/sub-account (config/campuses.json). Recommended.
SINCH_USE_CAMPUS_NUMBERS=true
SINCH_USE_CAMPUS_SUBACCOUNTS=true
# Fallback sender when a campus has no number (must be a 10DLC/toll-free number on the parent account)
SINCH_DEFAULT_SOURCE_NUMBER=+17746436322
# Fallback sub-account (leave blank to send as the parent account)
SINCH_ACCOUNT_ID=
# Optional staff heads-up text for every new lead (no visitor PII beyond first name)
SINCH_INTERNAL_NOTIFY_NUMBER=
# Optional override of the confirmation template. Placeholders: {{first_name}} {{campus_name}} {{service_or_date}} {{address}}
SINCH_CONFIRMATION_TEMPLATE=
# ---- Location services ------------------------------------------------------
# Approximate IP geolocation: none | header | ipapi_co | ipinfo | ip_api_com
GEOIP_PROVIDER=ipapi_co
GEOIP_API_KEY=
GEOIP_CACHE_TTL=3600
# ZIP lookup: zippopotam | nominatim | google
GEOCODE_PROVIDER=zippopotam
GEOCODE_API_KEY=
# Local testing helpers (never enable in production)
DEBUG_GEO=false
# ---- Anti-spam ----------------------------------------------------------------
# Optional Cloudflare Turnstile (free). Leave blank to rely on honeypot + timing + rate limits.
NEXT_PUBLIC_TURNSTILE_SITE_KEY=
TURNSTILE_SECRET_KEY=
MIN_FORM_SECONDS=3
RATE_LIMIT_SUBMIT_PER_10MIN=5
RATE_LIMIT_SUBMIT_PER_DAY=60
RETRY_BATCH_SIZE=25
# ---- Analytics & advertising (all optional; nothing loads when blank) -------
# implied = fire immediately (typical US ad landing page); opt-in = show a consent prompt first
NEXT_PUBLIC_ANALYTICS_CONSENT_MODE=implied
NEXT_PUBLIC_GTM_ID=
NEXT_PUBLIC_GA4_ID=
NEXT_PUBLIC_META_PIXEL_ID=
NEXT_PUBLIC_TIKTOK_PIXEL_ID=
# Google Ads conversion "send_to" value, e.g. AW-123456789/AbC-D_efG-h12_34-567
NEXT_PUBLIC_GADS_CONVERSION=