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>
6.8 KiB
6.8 KiB
Launch checklist
A. Items that require Waters Church approval before launch
Nothing below was fabricated; each item is either unverified or a legal/policy decision.
Facts to confirm (config/campuses.json → verify)
- Coordinates for every campus (derived from Google Maps links / OpenStreetMap; spot-check each pin).
- North Attleboro service times — campus page says 7:30, 9:30, 11:30 AM; the locations index page shows "11:30p" (assumed typo).
- Parking and arrival notes for each campus (currently empty; generic copy is shown instead).
- Woonsocket and Southcoast phone numbers — the main office number is used because the campus pages list none.
- Orlando — marked
launching(launch team only) and excluded from recommendations. Flipstatustoopenand add an SMS number when it opens. - Central "Text Us" number (
NEXT_PUBLIC_CENTRAL_SMS_NUMBER, default +1 508-695-1300) — who answers general texts? - Norwood uses
info@waterschurchnorwood.organd 781-762-3357 per its own page — confirm these are current.
Content placeholders (src/content)
faqs.tsitems flaggedconfirm: true: service length ("a little over an hour"), parking ("free on-site parking at every location"), accessibility ("step-free entrances").kids.tsitems flaggedplaceholder: true: first-time check-in steps, "arrive 15 minutes early", what to bring, special-needs accommodations.testimonials.tsis empty → section is hidden. Add real, permissioned quotes or leave hidden.- Headline and copy tone (
copy.ts).
Legal / compliance (not legal advice — route to Waters Church's adviser)
- SMS consent language (
consent.ts→sms.detail): TCPA/CTIA disclosures, frequency, "Msg & data rates may apply", STOP/HELP, consent not a condition. Confirm the number is registered (10DLC campaign / toll-free verification) for this use case. - Email consent language and single vs. double opt-in (
MAILCHIMP_DOUBLE_OPTIN). - Privacy Policy at waterschurch.org/privacy covers this subdomain, SMS, geolocation estimate, analytics and ad pixels. Add a Terms URL (
NEXT_PUBLIC_TERMS_URL) if one exists. - Data retention: set
LEAD_RETENTION_DAYS(0 = keep forever). Decide who may runexport-leads.phpand where exports live. - Analytics consent mode:
implied(default) vsopt-inbanner. - Location estimation wording (
consent.ts→locationBlurb). - Bump
consent.versionif any consent text changes.
B. Post-deployment verification
Hosting
https://visit.waterschurch.org/loads;http://andwww.redirect (301) tohttps://visit.waterschurch.org/.- SSL padlock valid (AutoSSL) — check with https://www.ssllabs.com/ssltest/.
/BUILD.txtshows the expected build;/404.htmland a random URL return the branded 404./api/health.php→"ok": true,integration_mode: "live"./api/lib/Config.php,/api/config/campuses.json,/api/cron/retry-integrations.php→ 403.- Response headers include
Strict-Transport-Security,X-Content-Type-Options, cache headers (immutableon/_next/static,must-revalidateon HTML),Content-Encoding: br|gzip. - Old Church Center redirect removed.
Location detection
- On a phone off Wi-Fi: a campus is recommended with the "based on your general area" badge.
- Deny "Use my precise location" → friendly message, page still usable.
- ZIP search: 02763 → North Attleboro, 02062 → Norwood, 02895 → Woonsocket, 02878 → Southcoast, 33572 → Apollo Beach, 32789 → Apollo Beach (far away notice), 90210 → far away notice.
- Bad ZIP (
abc,1234) → inline error, no crash. - Choose a different campus → form step 1 updates to match.
Form, consent and integrations (use your own email/phone)
- Email consent only → Mailchimp contact created with tags; no text sent.
- SMS consent without phone → blocked with an inline error.
- SMS + phone → confirmation text arrives from the campus number within a minute; Mailchimp
Visit:SMS Opt-Intag present. - Neither box → lead stored (export shows it), nothing sent.
- Reply STOP to the text → opt-out confirmed by Sinch; resubscribe afterwards.
- Double-tap "Send" / refresh and resubmit → one lead, one text (
duplicate: truein the network response). - Temporarily set a wrong
SINCH_API_SECRET→ submit → confirmation still shows,sms_status = retry, cron log shows retry; fix the secret → text arrives on the next cron run. - Confirmation screen shows campus, times, directions, "Text Us a Question" with the campus number.
- Mailchimp journey/automation fires for the new contact.
Attribution and analytics
- Visit with
?utm_source=facebook&utm_campaign=test&fbclid=abc&v=b, submit → export shows the attribution JSON andvariant = b; Mailchimp tags includeVisit:Platform Facebook,Visit:Campaign test. - Visit with no parameters and with malformed ones (
?utm_source=<script>) → still works, values sanitised. - GTM/GA4 debug view shows
landing_page_view,campus_recommended,campus_selected,plan_visit_started,plan_visit_step_completed,plan_visit_submitted,plan_visit_success,text_us_clicked,directions_clickedwithcampus,platform,campaign,device_category,variant. - Conversion events fire only after
plan_visit_success(check Meta Events Manager / Google Ads test conversion). - No email/phone/name appears in any analytics payload.
Text Us
- iPhone and Android: header, hero, floating button and campus cards open Messages with the pre-filled text, editable, to the right number.
- Desktop: the
sms:link degrades gracefully (Messages app on macOS, otherwise no-op) — consider a visible phone number if desktop traffic is significant.
Consent records
- Export a lead:
consent_version,consent_at,email_consent,sms_consent, hashed IP present; no raw IP or precise coordinates stored.
Performance & accessibility
- Lighthouse mobile (Chrome DevTools, "Slow 4G"): Performance ≥ 90, Accessibility ≥ 95, no CLS from hero/fonts.
- 320 px, 375 px, 430 px, 768 px, 1280 px widths: no horizontal scroll, tap targets ≥ 44 px.
- Keyboard only: skip link → header → campus cards → FAQ accordions → form steps → submit; focus always visible.
- Screen reader: form errors announced (
role="alert"), step heading focused on step change, confirmation announced (role="status"). prefers-reduced-motion: no animation.
Operations
- Cron job runs every 5 minutes (
cron.loggrows withretry:lines). - Someone owns
app.logreview and the leads export cadence. .envbacked up somewhere safe (it is not in the repo).