Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
visit.waterschurch.org — Plan Your Visit landing page
A focused, mobile-first advertising landing page for Waters Church that helps first-time visitors find their closest campus, know what to expect, and plan a visit. Built to deploy on the church's cPanel/Apache hosting as a static site with a small PHP API.
Ads (Facebook · Instagram · X · Google · TikTok)
│ utm_* / gclid / fbclid / ttclid / twclid
▼
┌──────────────────────────────┐ ┌────────────────────────────────────┐
│ Static site (Next.js export)│ JSON │ PHP API (public/api) │
│ hero · campus finder · │ ─────▶ │ validate → store lead (SQLite/MySQL)│
│ what to expect · kids · form│ │ → Mailchimp → Sinch Engage → retry │
└──────────────────────────────┘ └────────────────────────────────────┘
Documentation
| Document | Audience |
|---|---|
| docs/SETUP.md | Developers: run locally, test without sending messages, configure Mailchimp / Sinch / tracking, edit campus content |
| docs/DEPLOY-CPANEL.md | Site administrator: create the subdomain, SSL, upload, private config, cron, updates |
| docs/LAUNCH-CHECKLIST.md | Everyone: post-deployment verification and the list of items that need human/legal approval |
| .env.example | Every configuration key, with placeholders |
| config/campuses.json | Campus names, addresses, service times, SMS numbers (single source of truth) |
Quick start
npm install
cp .env.example .env # public build settings (safe to commit? no — .env is git-ignored)
cp .env.example private/.env # local PHP API settings (INTEGRATION_MODE=mock)
npm run dev # Next.js on http://localhost:3000
npm run dev:api # PHP API on http://127.0.0.1:8080 (needs PHP 8.1+ locally)
Point the frontend at the local API by setting NEXT_PUBLIC_API_BASE=http://127.0.0.1:8080/api
in .env (and add http://localhost:3000 to ALLOWED_ORIGINS in private/.env).
Or preview the production build in one process (static files + PHP together):
npm run build && php -S 127.0.0.1:8080 -t out
Scripts
| Command | What it does |
|---|---|
npm run dev |
Next.js dev server |
npm run dev:api |
PHP built-in server for the API (public/) |
npm run build |
Optimize images → next build (static export) → post-build (.htaccess, campus config) → out/ |
npm run package |
Zip out/ into dist/ for upload through cPanel File Manager |
npm test |
Vitest: distance, ZIP fallback, validation, consent, attribution, analytics, form flow (keyboard) |
npm run test:php |
PHP suite: validation, Mailchimp/Sinch mapping, idempotency, partial failure + retry, HTTP end-to-end |
npm run typecheck / npm run lint |
TypeScript and ESLint |
npm run images |
Regenerate responsive AVIF/WebP/JPEG images from assets/source |
Project layout
config/campuses.json campus data (read by TS and PHP)
src/config/ site settings, campus loader, image manifest
src/content/ copy, FAQs, kids info, consent text, testimonials
src/components/ page sections (Hero, CampusFinder, PlanVisitForm, …)
src/lib/ geo, attribution, analytics, schema, api client
public/api/ PHP endpoints + lib (Mailchimp, Sinch, GeoIp, Geocode, LeadProcessor)
public/api/cron/ retry-integrations.php, export-leads.php (CLI only)
deploy/htaccess.root Apache config copied to out/.htaccess at build
assets/source/ original logos/photos (see SOURCES.md)
tests/ Vitest (TS) and tests/php (PHP)
docs/ setup, deployment, launch checklist
Architecture decision (cPanel)
The target host is cPanel on Apache (confirmed: waterschurch.org:2083 answers, server header Apache).
Whether the account offers the Node.js Application Manager could not be verified without logging in,
so the build targets the lowest common denominator that every cPanel account supports:
- Frontend: Next.js App Router + TypeScript + Tailwind, compiled with
output: "export"to plain HTML/CSS/JS. No Node process runs in production. - Backend: PHP 8.1+ endpoints (cPanel ships PHP 8.x with cURL and PDO/SQLite). Secrets live in a
.envfile outside the document root. Leads are stored in SQLite (or cPanel MySQL) before Mailchimp/Sinch are called; failures are retried by a cPanel cron job. - Location: approximate server-side IP lookup (city-level, rounded, cached by hashed IP) for the recommendation; precise browser geolocation only on request; ZIP search always available.
If Waters Church later confirms Node hosting, the frontend needs no change; the PHP layer could be swapped for route handlers, but there is no functional reason to.
Source of truth: Gitea
The repository lives at Waters-Church/visit.waterschurch.org on the church's Gitea
(ssh://git@chronicles-ab.waterschurch.org:3022/Waters-Church/visit.waterschurch.org.git).
Clone it to a normal local folder (for example ~/Sites/visit.waterschurch.org); do not develop
inside Google Drive, which fights with node_modules and build output. The original copy in the
"Websites" shared drive is kept only as a snapshot and is no longer updated.
Facts and placeholders
Campus addresses, service times, phone numbers, kids age groups and safety practices were verified
against waterschurch.org on 2026-09-22. Items that could not be verified are null in
config/campuses.json (listed under each campus's verify array) or flagged placeholder: true /
confirm: true in src/content/. Testimonials are intentionally empty. See
docs/LAUNCH-CHECKLIST.md.