2026-09-22 16:58:35 -04:00

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 .env file 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.

S
Description
Plan Your Visit landing page for Waters Church — Next.js static export + PHP API, deployed to cPanel at https://visit.waterschurch.org
Readme
6.5 MiB
Languages
TypeScript 52.9%
PHP 39%
JavaScript 3.3%
Shell 2.7%
CSS 2.1%