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>
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
||||
# =============================================================================
|
||||
# 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=
|
||||
Reference in New Issue
Block a user