SaaSSports techIn-browser ML

ClubPulse // Matchday media control for amateur rugby clubs

Matchday media control for amateur rugby clubs — fixtures to branded graphics in one app

Next.js 15React 19Supabasehtml-to-image graphicsESRGAN + BiRefNet (in-browser)Instagram / Facebook / X publishing
37
Figma-aligned graphics templates — preview → PNG → download/publish
3
Social platforms published to — Instagram, Facebook Pages, and X
13
Delivery areas from auth and tenancy through live match control to social publishing
01 — The brief

ClubPulse is built for the club secretary or media volunteer who runs Saturday matchday socials — the person otherwise juggling a notepad, Canva, and three social apps. Instead, they run the whole cycle in one place: set up the club, build the fixture list and squad, record live events as they happen, generate branded Instagram graphics, and publish straight to Instagram, Facebook, and X.

Graphics render in the browser via html-to-image. Crest cleanup and player cutouts use in-browser ML — ESRGAN via UpscalerJS/TF.js, and BiRefNet via Transformers.js — with deterministic fallbacks. Crests are never generatively redrawn; the product improves what’s uploaded, it doesn’t redesign it.

02 — What we built

The product surface

Designers author templates in Figma; they ship as React layouts at Instagram design resolution. The operator previews the exact PNG that will publish — no Canva, no server-side rendering farm.

01

Auth & club tenancy

One account per club, gated dashboard, and a setup checklist, with a strict one-user-to-one-club tenancy model and middleware-protected routes.

02

Logo Cleanup Studio

Messy crest upload → transparent colour / greyscale / circle PNGs. Used for club crests, opponent logos, and sponsor logos alike.

03

Fixtures & squad

Season fixture CRUD with shared opponent/competition directories, plus a player roster with positions, availability, photos + AI cutouts, and per-fixture Starting XV + bench selection.

04

Live Match Control

A phase machine, minute clock, scoring and discipline events, and undo — the operational core of matchday, recording the game as it happens.

05

Match Graphics Engine

37 Figma-aligned templates, multi-format export (portrait 1080×1350, square, story), preview → PNG → download/publish.

06

Social publishing

OAuth + publish to Instagram, Facebook Pages, and X, with an editable auto-seeded caption, per-platform toggles, and a posts history.

03 — Architecture and stack

Decisions, not just dependencies.

The graphics pipeline runs entirely client-side: select an event → buildGraphicContext() hydrates club/fixture/event/squad/sponsor data → MatchGraphicRenderer mounts the layout → MatchGraphicCanvas previews it → html-to-image captures a PNG → optional crop/pad → download and/or publish. The club crest, opponent crest, live score and minute, player name/number/photo cutout, sponsor strip, and the club’s brand colours and typography are all composed automatically into every graphic.

Hosted on Vercel with per-pull-request preview environments; local development mirrors production via Supabase in Docker, with seed scripts for demo clubs and players. A weekly cron handles Instagram token refresh. The product is designed to degrade gracefully — ESRGAN, BiRefNet, and optional AI logo advice all soft-fail without ever blocking an upload, save, or publish. Dev harnesses include a logo-lab for crest regression testing against real UK club badges, and a graphics lab.

04 — Delivery highlights

What was hard, and how we shipped it.

  1. 01

    Match Graphics Engine

    Designers author templates in Figma; they ship as React layouts at Instagram design resolution. The operator previews the exact PNG that will publish — no Canva, no server-side rendering farm. 37 shipped templates span scoring, cards, substitutions, half/full-time, line-ups, milestones, and fixtures grids.

  2. 02

    Live Match Control

    The operational core of matchday — a console for recording the game as it happens. Phases run pre → first → half → second → fulltime → full; the scoring pad covers Try (5), Conversion (2), Penalty (3), Drop goal (3), plus cards and substitutions; score is computed from the event timeline and written back to the fixture.

  3. 03

    Logo Cleanup Studio

    Identity-preserving, not generative: a triage step routes flat/safe backgrounds to chroma-key, complex ones to BiRefNet, and failures to flood-fill; ESRGAN-slim super-resolution runs in-browser on self-hosted weights; and BiRefNet-lite-512 does alpha matting via Transformers.js in a Web Worker so the UI stays responsive.

  4. 04

    Social publishing

    Clubs connect Instagram, Facebook Pages, and X via OAuth; from the graphics wizard the secretary gets an editable caption auto-seeded from the event, a separate hashtags field, and per-platform publish toggles — publishing runs in parallel with per-platform success/failure toasts, and Download PNG is always available.

  5. 05

    Sponsors

    Club and player sponsors with Fixed, Rotation, or Hybrid placement modes, 1–5 slots that can be individually locked or rotated, and empty-slot fillers — auto-composed onto every graphic, with player sponsors auto-resolving onto that player’s graphics on publish.

Looking at a project that sits at this kind of seam?

Bring us the architecture, the constraints, and the ship date. We will bring the rest.