dan’s digital workshop
Back to projects

Split-Flap Board — a departures board for the wall, not the browser

A browser-built split-flap arrivals board — live weather, flap-style animation, colour and emoji messages posted through a private control page — now with a tightened message layout, still honestly short of a real build check and a real TV.

Next.jsTypeScriptCloudflare PagesCloudflare KVFramer Motion

Problem

I wanted something physical-feeling on the wall, not another dashboard tab. Real split-flap boards have a specific texture: mechanical, slightly imperfect, satisfying to watch update. The brief was to get that feeling right in a browser — running eventually full-screen on a 65" Samsung Frame TV — with live weather permanently on the board and a place to post short messages.

Approach

Built in Next.js, TypeScript, Tailwind and Framer Motion for the flap animation, on an 8-row by 32-character grid. The first build assumed a normal server for the message API — wrong assumption. The actual host is a static-export Cloudflare Pages site with no server runtime at all, so the backend had to be re-platformed onto Cloudflare Pages Functions and Cloudflare KV instead, with a shared-password gate on the private control page using Cloudflare's own middleware convention rather than Next's.

Outcome

Live at danbuildsstuff.dpdns.org/board, with messages posted through a private, password-gated control page at .../board/control. Post a message, in colour, with emoji if you want them, and the board flaps it into place row by row, left to right, with an audible click as each row lands. It remembers the last ten messages and rotates through them, twenty-five seconds each, jumping straight to whatever's newest the moment it's published — live weather (Open-Meteo, no API key) sits permanently on the bottom two rows, and a dad joke works its way in every minute and a half, now with its own laugh emoji, so the board's never just sitting there dead. A polish round tightened the message layout so shorter posts pack from the bottom of their five rows instead of leaving an odd gap, with tests updated to match. Getting there included one real production scare: a placeholder KV ID left in a config file broke the live deploy, a five-minute fix once found. Still open, and still honest about it: this has been through logic checks and a full test pass, but not yet a real npm install and build — the Cloudflare Pages Functions are the first backend code this repo has ever had, and that's exactly where a real build error would show up if there is one. Also still missing: a proper history page (the data's already being written, nothing reads it yet), real per-person auth beyond the single shared password, and the TV itself, which isn't connected.

Lessons learnt

Two lessons that'll outlast this specific board — both get the full write-up in Workshop Notes. The environment I build in is never automatically the environment the thing runs in: built the backend assuming a normal server, then had to re-platform onto Cloudflare Pages Functions and KV once the real static-export hosting became clear — now I check the deployment target before writing backend code, not after. And partial verification — traced logic, stubbed type-checks, tests run outside the normal runner — still isn't the real thing: the first real compile on the real machine kept finding one more thing, every time.