Skip to content

A content hub that keeps 40 franchise sites on-brand without a bottleneck

A headless CMS where corporate manages shared brand content centrally while each of 40 franchise locations publishes its own class schedule and local promotions without touching code.

Cedar Falls · club page1 unpublished change
Signed in as Renée Alvarez · Location manager · scope: cedar-falls only
PreviewPublish 1 change Thu, 09/17/2026RA
/clubs/cedar-falls·Brand sections, lockedLocal sections, written here
Site headersiteChrome · v9Head office
TallwaterClassesMembershipsCoachesClubsJoin
Membership plansmembershipPlan · v6Same at all 40 clubs
Off-peak$29.00 /moWeekdays 10 AM – 4 PM, weekends
Standard$39.00 /moYour club, any hour, all classes
All clubs$54.00 /moAny of the 40 Tallwater clubs
Class scheduleEditing11 classes · 69 of 160 places left
DayTimeClassCoachLengthPlaces left
Mon6:00 AMStrength CircuitJada Whitlock45 min5 / 16
Mon12:15 PMLunch HIITTom Brekke30 min5 / 12
Tue6:00 PM 5:30 PMSpin 45Marcus Oyelaran45 min4 / 16
Tue7:00 PMMobility FlowPriya Castellano50 min8 / 12
Wed6:00 AMStrength CircuitJada Whitlock45 min7 / 16
Thu12:15 PMLunch HIITTom Brekke30 min4 / 12
Thu5:30 PMSpin 45Marcus Oyelaran45 min3 / 16
Fri6:00 AMKettlebell BasicsJada Whitlock40 min6 / 12
Sat8:00 AMSpin Long RideMarcus Oyelaran75 min9 / 16
Sat9:00 AMOpen CircuitJada Whitlock60 min11 / 20
Sun10:00 AMYoga for LiftersPriya Castellano60 min7 / 12
Local offerLive · signed off 8:31 AMby Owen Fairbanks
Two weeks freeJoin Cedar Falls by 09/30 and your first two weeks are on us. Nothing to pay today.Written 8:12 AM
Legal footerlegal · v12Corrected once for all 40
Memberships are subject to the Tallwater Fitness membership agreement. Class places are not guaranteed until booked.

Change ready to publish

1 entry
class/cedar-falls/tue-spin-45
Tue · Spin 45Coach Marcus Oyelaran5:30 PM6:00 PM
OwnerLocal · Cedar FallsYour permissionPublish, own clubRegenerates1 page on 1 site

Your reach on this page

From your location, in the API
Site headerView onlyMembership plansView onlyClass schedulePublishHours & club detailsPublishLocal offerDraft · regional sign-offLegal footerView only

Publish path

No corporate reviewer on a class time
Saved as a draft8:40 AMScope checked in the APIentry club = cedar-fallsRegenerate /clubs/cedar-fallsonly this pageLive on the club siteon publish
Median local publish this week: 4 min · was 3 days

Who, what, and how long

Industry
Healthcare & Dental Practices
Duration
9 weeks
Cooperation model
Fixed price
Services
Content modelingEditor rolesHeadless CMS build
Integrations
HL7 FHIRTwilioStripeDocuSign
Technologies
Next.jsTypeScriptHeadless CMSGraphQLRole-based access controlIncremental static regeneration
Team
1 Project lead1 Product designer2 Frontend engineers1 Backend engineer

Client name withheld under NDA. Engagement details are shown to the extent our agreement permits.

Two kinds of content

Brand content and location content modeled as distinct related types, never one mixed pool.

Brand content and location content are separate types with a defined relationship, never one pool with a flag on it. A location page composes centrally owned brand blocks with its own hours, staff and offers, so a national campaign lands everywhere without a franchisee having to paste it, and a franchisee editing their own page can't alter the campaign.

What shipped
  • Brand and location modeled as distinct related types
  • Location pages compose central blocks with their own content
  • National campaigns land without franchisee action
Content library
Two kinds of entry, related but never mixed · nine content types
View API schema Thu, 09/17/2026LK
Brand sections84Owned by head office · go to all 40 sites
Location entries1,120Owned by one club · go to exactly one site
Clubs on the template4012 · 9 · 11 · 8 across four regions
Content types95 brand · 4 location

Content types

Owner is the type, not a flag on the entry
TypeOwnerHoldsEntries
Site chromeBrandHeader, nav, footer11
Brand storyBrandAbout, method, values18
Membership plansBrandPrices, terms9
Legal & complianceBrandWaivers, footer copy14
Campaign sectionsBrandNational promotions32
ClassesLocationTimetable entries440
Coach profilesLocationBios, specialties160
Hours & club detailsLocationStreet, hours, phone280
Local offersLocationClub promotions240

How a club page is composed

/clubs/cedar-falls
From head office Site chrome Membership plans Campaign section Legal footerReferenced, not copied: one entry, forty pages
Shared templateHeaderClub hero · street, hoursCampaignPlans · $39.00Timetable · 11Coaches · 4Local offerFooter
From Cedar Falls Hours & details Classes · 11 Coaches · 4 Local offerWritten here, related to this club and no other

Latest entries

A campaign lands everywhere; a class time lands once
EntryTypeOwnerGoes toByPublished
class/cedar-falls/tue-spin-45ClassLocationCedar Falls onlyRenée AlvarezToday 8:40 AM
campaign/autumn-resetCampaign sectionBrandAll 40 clubsHead officeToday 8:22 AM
localOffer/ames/two-weeks-freeLocal offerLocationAmes onlyKeisha MorrowToday 8:05 AM
On screen

The content library: 84 brand sections that go to all forty sites beside 1,120 location entries that go to exactly one, nine content types owned by type instead of by a flag, and how one club page composes central blocks with its own.

Roles & scope
Four roles against nine content types · scope comes from the location a user belongs to
Run permission tests Thu, 09/17/2026LK

What each role may do

Enforced in the API; the interface only reflects it
Content typeHOHead office editorBrand types · all 40 clubsRMRegional managerOwn region · 8 to 12 clubsLMLocation managerOwn club onlyCOCoachOwn classes & profile
Brand content · owned by head office
Site chromePublishViewViewNo access
Brand storyPublishViewViewNo access
Membership plansPublishViewViewNo access
Legal & compliancePublishViewViewNo access
Campaign sectionsPublishViewViewNo access
Location content · owned by each club
ClassesViewPublishPublishDraft
Coach profilesViewPublishPublishDraft
Hours & club detailsViewPublishPublishNo access
Local offersViewSign offDraftNo access

A tampered URL returns nothing

Signed in as Renée Alvarez
# /clubs/cedar-falls/classes edited to /clubs/waterloo/classesquery { location(slug: "waterloo") { classes { id time } } }scope: user.location = "cedar-falls"
{ "data": { "location": null } }The query never returns another club’s content,so there is nothing on screen to hide.

Set by the two-club pilot

Before the other 38 clubs
Hours devolved to location managersA class time or opening hour is published by the club that runs it.
Offers held at regional levelA club drafts its offer; its regional manager signs it off.
On screen

Four roles against nine content types, with location managers publishing classes and hours while offers are signed off regionally, a tampered club URL returning null from the API, and the two rules the pilot settled.

Scoped editors

Each location's staff can reach only their own content, and the API enforces it.

Editor scope is derived from the location a user belongs to and enforced in the API, not in the interface. A franchisee can't reach another site's content by editing a URL, because the query never returns it. Roles are granular enough that a manager can update hours while only a regional lead can change an offer, which is what made devolving editing acceptable to head office.

What shipped
  • Scope enforced in the API, not by hiding interface
  • URL tampering returns nothing, never another site's content
  • Granular roles: hours devolved, offers held regionally
Autumn Reset · v3Scheduled Mon, 09/21/2026 · 5:00 AM CT
Campaign section · owned and versioned by head office · goes to all 40 clubs
Compare with v2Edit schedule Thu, 09/17/2026LK

Brand · head office Section preview

Rendered in the shared template
TallwaterAutumn Reset.
Start the season strong.
Standard membership from $39.00/mo at every Tallwater club.Find your club
On each club pageLands above the club’s own timetable. The club’s entries aren't touched.

Version history

One entry · corrected once, served forty times
Ver.ChangeBySavedState
v3Headline shortenedLauren Kessler09/16/2026Scheduled
v2Price now reads plans entryLauren Kessler09/11/2026Superseded
v1First autumn draftSam Ortiz09/08/2026Superseded

What this rollout touches

Incremental regeneration, not a full rebuild
Clubs40 of 40No franchisee has to paste it
Pages regenerated802 pages per club, nothing else
Location entries changed01,120 left exactly as clubs wrote them
Franchisee actions needed0It lands on the schedule

Rollout by region

40 clubs · one template
Northeast12 clubs · 24 pages
Southeast9 clubs · 18 pages
Midwest11 clubs · 22 pages
West8 clubs · 16 pages
Each square is a club, waiting on the 09/21 schedule.

Last correction

Legal footer · v12
Class places are guaranteed on joining. Class places are not guaranteed until booked.
Corrected Once, in one entryServed on Every page of all 40 sitesSave to live About two minutes, no deploy

Scheduled brand sections

6 in queue
Autumn Reset · home band09/21 · 5:00 AMAutumn Reset · join page band09/21 · 5:00 AMBrand story · coaching method09/22 · 6:00 AMand 3 more

Central brand control

On screen

A campaign section versioned centrally and scheduled onto all forty clubs across four regions, 80 pages to regenerate and no location entry touched, with a legal footer correction made once for every site.

Corporate pages stay centrally owned and versioned across all forty sites.

Corporate pages are owned centrally and versioned, so the legal footer, the brand story and the compliance copy are the same forty times over and can be corrected once. Publishing a brand change regenerates only the affected pages across all forty sites, which keeps a wording fix a two-minute operation instead of a scheduled deploy.

What shipped
  • Corporate pages centrally owned and versioned
  • One correction propagates across all forty sites
  • Incremental regeneration: a wording fix takes minutes
Introduction

What we were brought in to do

Forty franchise locations each needed to publish their own class schedules and local promotions, but every change went through a single corporate webmaster, so simple updates took days.

Forty franchised locations, each running its own class timetable and local promotions, all published by one corporate webmaster. A location wanting to move a Tuesday class emailed the request and waited. The engagement was commissioned when a franchisee started running a parallel unofficial page on a social platform because the official one couldn't keep up with their schedule.

Content Platform Engineering

The problem

Where the old way broke

Corporate brand pages and location-specific content lived in the same undifferentiated CMS with one set of editor permissions, so a location manager couldn't update a class time without going through the same queue as a brand-wide campaign change.

Brand pages and location pages sat in the same CMS with one set of editor permissions, so there was no way to let a location manager change a class time without also letting them change the brand's compliance copy. The safe answer had been to let nobody edit, which put a corporate webmaster in the path of forty locations' routine timetable changes.

We modeled brand content and location content as distinct, related types, gave each location's staff scoped editor access to only their own content, and kept corporate brand pages centrally controlled, all delivered through one API to a shared site template.

What we built together

  1. 01

    Separated brand-level and location-level content into distinct, related types

    Brand content and location content are distinct related types, never one pool with a flag, which is what makes a scoped permission expressible at all.

  2. 02

    Built scoped editor roles so location staff can only touch their own content

    Enforcing scope in the API, not just the interface, was the point corporate needed convincing of, since a franchisee doesn't have to be devious to edit a URL.

  3. 03

    Kept corporate brand pages centrally controlled and versioned

    Corporate pages stay centrally owned and versioned, so the legal footer and compliance copy are the same forty times and correctable once.

  4. 04

    Delivered everything through one API to a shared, brand-consistent template

    Two locations piloted the scoped role first, which is why hours devolved to managers while offers stayed at regional level.

Process

Phase by phase

  1. Phase 1: Separate

    Brand from local

    Separated brand-level and location-level content into distinct, related types with an explicit relationship.

    • Content model
    • Relationship map
  2. Phase 2: Scope access

    Forty editors, forty scopes

    Built scoped editor roles so location staff could only touch their own schedules and promotions.

    • Role definitions
    • Permission tests
  3. Phase 3: Centralise

    Brand pages, versioned

    Kept corporate brand pages centrally controlled and versioned so a change rolls out consistently.

    • Version control
    • Rollout mechanism
  4. Phase 4: Deliver

    One template, forty sites

    Delivered everything through one API into a shared brand-consistent template.

    • Delivery API
    • Shared template
    • Location onboarding guide
Activity · last 7 days
Every publish across the 40 clubs, and what is still waiting
09/10 – 09/16/2026 Thu, 09/17/2026LK
Publishes this week412389 by clubs · 23 by head office
Median time to publish4 minWas 3 days by email to the webmaster
Clubs self-publishing40 of 40Published unaided in the first quarter
Webmaster queue−85%That role's own tickets, before and after

Publishes by day

ClubHead office
71
65
56
36
73
67
44
Thu 09/10Fri 09/11Sat 09/12Sun 09/13Mon 09/14Tue 09/15Wed 09/16

Approvals

12 local · 6 scheduled brand
Local offers awaiting regional sign-off · 12Local offer · Bring a friend FridaysAmes · Keisha Morrow6 minLocal offer · Student rate weekPortland Pearl · Dev Raman11 minLocal offer · Two weeks freeChapel Hill · Ana Pereira14 minLocal offer · Open house SaturdayWorcester · Liam Cho22 minBrand sections scheduled · 6Autumn Reset · home and join bands09/21 5:00 AMNo class time waits on a corporate reviewer

Recent publishes

Save to live, per entry
EntryGoes toOwnerPublished byTookAt
Class · Tue Spin 45 moved to 6:00 PMCedar FallsLocationRenée Alvarez3 min8:43 AM
Hours · Sat opens 7:00 AMBoise BenchLocationGrace Tollefson2 min8:37 AM
Local offer · Two weeks freeCedar FallsLocationRenée Alvarez → Owen Fairbanks19 min8:31 AM
Brand story · Our coachesAll 40 clubsBrandLauren Kessler5 min8:15 AM
Coach profile · Priya CastellanoCedar FallsLocationRenée Alvarez4 min8:02 AM
On screen

A week of activity: 412 publishes at a median of four minutes against the old three days, split by day between clubs and head office, the queue of twelve local offers and six scheduled brand sections, and recent publishes with their save-to-live time.

Operational results after launch

Days → minutes

Time to publish a local update

40 of 40

Locations self-publishing

−85%

Corporate webmaster queue

Time to publish a local update compares the previous email-and-wait cycle with the current self-serve one. Forty of forty self-publishing is a count of locations that published at least once unaided in the first quarter. The webmaster queue reduction is that role's own ticket count, before and after.

Client name withheld under NDA. Figures are approximate, drawn from the engagement’s own reporting.

Ways of working

About our collaboration

A cross-functional team of 4 worked on a fixed price basis over 9 weeks, covering Content modeling, Editor roles, Headless CMS build. We ran daily standups with their own lead in the room, and a demo at the end of every sprint. Scope changed twice during the engagement, and both times the change was priced and agreed before work started.

Nine weeks, fixed price, with the content split (brand versus location) settled with corporate marketing in week one, because everything else follows from it. Two locations piloted the scoped editor role before the other thirty-eight, and the granularity changed as a result: hours devolved to managers, offers held at regional level.

What it settled

What we'd carry into the next one

03
  1. 01

    The bottleneck was corporate reviewing local content it had no reason to review.

    Corporate had been reviewing class times it had no basis to have an opinion about. The queue existed because permissions couldn't tell the two kinds of change apart.

  2. 02

    Scoped permissions turned forty potential brand violations into forty independent editors.

    Scoping made devolution safe. Nobody had been given access because access had been all-or-nothing, not because the franchisees couldn't be trusted.

  3. 03

    One template is what keeps forty sites on-brand. The CMS alone wouldn't have.

    The template is what holds the brand, not the CMS: forty editors with the same content model and no shared template would still produce forty different sites.

One club page, five sections, two owners

The club publishes its timetable. It can’t touch the price.

Take the Cedar Falls manager’s seat. Pick a section of her page and try to change it: local sections go live on her site alone, the offer waits for her regional manager, and brand sections are refused by the API. Switch tabs, or use the arrow keys once one is focused.

Signed in as Renée Alvarez · Location manager · scope: cedar-falls head office this club
Local · Cedar FallsYou may: Publish, own club
class/cedar-falls/tue-spin-45
On the page nowTue · Spin 45 · 5:30 PMThe club's changeTue · Spin 45 · 6:00 PM
  1. Draft savedby Renée Alvarez0:00
  2. Scope checked in the APIentry club = cedar-falls ✓0:01
  3. Page regenerated/clubs/cedar-falls only · 1 page0:20
  4. Live on the club siteNo other club touched0:25

Nothing sent yet

Step times are illustrative, not measured, and exclude the time a person spends writing. The recorded figure is the median publish across the 40 clubs in a week: four minutes, against 3 days before.

Architecture

From a club manager’s save to the one page it belongs on

Forty clubs write into one content model through one API, and the shared template is what keeps forty sites on brand. Who may write what is decided in the API, before anything is stored.

  1. 01 · Edit
    Hub editorHead office edits brand sections; each club's staff edit their own schedule and promotions, without touching code.
  2. 02 · Scope
    GraphQL API + role checkScope comes from the location a user belongs to and is enforced in the API. A tampered URL returns nothing.
  3. 03 · Model
    Brand & location typesDistinct related types, never one pool with a flag. A club page composes central blocks with its own entries.
  4. 04 · State
    Versioned brand entriesCorporate pages are owned centrally and versioned, so a footer or compliance line is corrected once for all forty.
  5. 05 · Deliver
    One template, 40 sitesNext.js with incremental regeneration: a change rebuilds only the affected pages, so a wording fix takes minutes.
Devolved, not exposed

Forty editors, one brand, no way into another club’s page

Scope is enforced, not trusted

Editor scope is derived from the location a user belongs to and enforced in the API, not by hiding parts of the interface. Editing a URL to reach another club returns nothing, because the query never returns it.

Compliance copy has one owner

Corporate pages, the legal footer and the brand story are owned centrally and versioned. A club editing its own page can't alter them, and a correction is made once for all forty sites.

Rollouts leave clubs' work alone

Brand and location content are separate related types, so a national campaign lands on every site without a franchisee pasting it, and without touching the schedules and offers each club wrote.

Running many locations that should publish their own pages without breaking the brand? Scope your build in 3 minutes.

Scope your build
Have a project?

Let's talk

Running a large platform, shaping a first MVP, or getting a product ready for a funding round? Tell us where you are. We'll shape the process around it, and stay with you after launch.