Case study · Custom site + CMS

The booster club that owns its own site.

A custom static site and lightweight CMS replacing a hosted booster-club platform, for McKinney Boyd High School Theatre — Troupe 7052, in McKinney, TX.

Broadway Broncos Booster Club homepage built by RAWR

The booster club's web presence lived on BoosterHub, a hosted platform shared by thousands of booster organisations. It worked — but it was a tenant in someone else's product. The club owned its content, not its site.

The rebuild is a custom static site backed by a purpose-built CMS, a Postgres database, and serverless functions. Parents can join and pay online, sponsors can commit at four levels, the season calendar and photo gallery are managed by non-technical volunteers, and every page is search-optimised under the club's own domain.

10
Pages
5
API endpoints
~1,800
Lines of front-end code
84
Commits
The problem

Where the old site fell short.

Observations from the live BoosterHub site.

AreaBoosterHub
DomainA subdomain and numeric path on a shared platform (…boosterhub.com/home/9334)
DesignPlatform template; branding limited to a logo drop-in
CalendarPresent, but showing "No Upcoming Events" while the season was underway
PaymentsMembership and donations routed through the platform's own flow
PhotosNo dedicated production gallery
Content editingThrough the platform's admin, in its structure
SEOConstrained by the platform's markup and URL scheme
CostOngoing platform subscription

The most telling detail is the empty calendar. The feature existed; keeping it current was friction enough that it went stale — and a stale calendar is worse than none, because visitors trust it and get nothing.

The build

What the new site does.

01

Seven indexed pages

Home, Events, About, Join, Sponsors, Gallery, Contact — custom design throughout, with a full-bleed video hero, the club's navy and red, and a shared nav component.

02

Payments — three routes, one form

Pay online (PayPal, Venmo, or card, no account needed), send by Venmo/PayPal/Zelle with a pre-written memo, or pay by check. All three record the signup instantly; offline routes are marked pending until the treasurer confirms.

03

Server-verified pricing

The browser sends a level name; the server looks up the amount and re-verifies the captured total before recording. A tampered page can't invent a price. A 3% fee applies to online payments only — enforced and itemised server-side.

04

A self-advancing calendar

Each production carries multiple performance dates and showtimes. Start/end dates, the "Next Up" pick, and the ticker are derived automatically. Shows roll into Past Season on their own — the calendar can't go stale the way the old one did.

05

A CMS volunteers can use

No separate admin for content. An approved editor signs in, toggles Edit, and changes text and images directly on the live page — inline editing with revision history, image replacement, and a volunteer-managed photo gallery.

06

Admin dashboard

At /admin: every sign-up with CSV export and a payment column (PayPal / Venmo-Zelle / Check, paid vs pending), contact messages with read state, calendar management, and gallery categories. "Total raised" counts only confirmed money.

07

Built for search

Every page has a full SEO/AEO head — title, description, canonical, Open Graph, Twitter, and JSON-LD (PerformingGroup, TheaterEvent, OfferCatalog, ContactPage, breadcrumbs) — plus a sitemap, a robots.txt that welcomes AI answer engines, and clean URLs.

08

Purpose-built mobile

The design started desktop-only, with 474px of horizontal overflow on a phone. It now has a dedicated mobile layer — hamburger nav, collapsing grids, stacked hero buttons — verified at 390px and 320px with zero horizontal overflow.

The difference

Old vs new.

BoosterHubbroadwaybroncos.com
DomainShared subdomain, numeric pathsOwn domain, clean URLs
DesignPlatform templateCustom
CalendarManual; was showing noneMulti-date, self-advancing, with archive
Payment methodsPlatform flowCard, PayPal, Venmo, Zelle, check
Price integrityPlatform-managedServer-side, verified at capture
Offline paymentsRecorded as pending, tracked to confirmation
Photo galleryCategorised, volunteer-managed
Content editingPlatform adminInline, on the live page, with revisions
SEOPlatform-constrainedFull metadata, structured data, sitemap
MobilePlatform responsivePurpose-built layer
Data ownershipOn the platformClub's own Postgres, exportable
Hosting costSubscriptionFree tiers (Vercel, Supabase, Resend)
Under the hood

How it's built.

Static HTML on Vercel

No build step, no framework runtime — plain HTML from a CDN. Fast, cheap, and nothing to keep patched.

Supabase (Postgres)

Content overrides, revisions, events, gallery, sign-ups, and messages. Row-level security is the access control — a browser with the public key still can't write.

Vercel serverless functions

Anything needing a secret — PayPal order creation and capture, manual-payment recording, contact email. Keys live in env vars, never in the browser.

Resend

Transactional email sent from the club's own verified domain.

Browser ─── static HTML + CMS/checkout JS
   │
   ├── Supabase ── content · events · gallery · signups · messages   [RLS]
   │
   └── /api/* ──── PayPal (live) · Resend · service-role writes      [secrets]

Current state: PayPal live · 8 published events · 4 gallery categories · 7 URLs in the sitemap · 3% fee active.

The hard parts

Engineering notes.

A few problems worth recording, because they weren't obvious.

01

The payment popup that closed itself

PayPal opens its window synchronously on click, before validation runs — so rejecting an incomplete form closed the window it had just opened, and the button looked broken. Fixed by gating the buttons behind an overlay that blocks the click until the form is valid, plus a ?redirect=1 fallback to PayPal's hosted page for browsers that block popups.

02

Positional CMS keys and async content

The CMS numbers editable images by their position on the page. The events section renders after a database fetch, so its poster claimed an index a homepage image already owned — editing one silently changed the other. Fixed by excluding data-driven regions from tagging and adding a used-key guard.

03

A display:none file input

Safari refuses to open the file picker for an input that isn't rendered, so upload buttons silently did nothing for one admin while working for another. The inputs are now rendered but visually hidden.

04

A checkbox stretched to 190px

A mobile rule setting width:100% on inputs caught checkboxes too, turning each volunteer-interest checkbox into a long bar that shoved its label out of the row. Page-level overflow measured clean the whole time — the distortion was entirely inside the label.

Outcome

The club owns everything now.

The club now owns its site, its domain, its data, and the ability to change any of it without a developer. Parents can join and pay however they prefer; the season calendar keeps itself current; production photography has a home; and every page is properly indexed under the club's own name.

Running cost is the domain.

Need a site your organization actually owns?

We build custom sites — React front ends, WordPress or custom CMS, payments, and the SEO to get found. Based in Plano, TX.

Start a project