Work Workout 24/7

A gym site the owner can actually run

The original WordPress site needed a developer for every price change. The rebuild models the business in the CMS instead of in pages — adding a town means adding a document, and the route, the navigation, and the metadata follow from it.

Role
Sole developer — content model, build, and ongoing maintenance
Stack
Next.js 16 · React 19 · TypeScript · Tailwind CSS · Sanity · Upstash Redis · Resend · Vercel
01

A content model, not a page builder

Locations, membership plans, and FAQ entries are modelled as document types sharing a common SEO field object, rather than as free-form pages. One dynamic route renders any location from its slug, so Osakis and Wells are the same code path and cannot drift apart over time.

02

Tag-scoped revalidation instead of rebuilds

A CMS webhook verifies its payload signature and purges only the cache tags belonging to documents that actually changed. A price edit is live in seconds, and nothing unrelated is invalidated — the site stays static-fast without the owner waiting on a full rebuild.

03

A contact form that fails in the right direction

The form pairs a honeypot with a Redis-backed sliding-window rate limiter. Serverless functions do not share memory, so in-process limiting would have been decorative — hence an external store.

The limiter fails open by design. If Redis is unreachable, submissions still go through: silently dropping a real enquiry from a paying customer is a worse outcome than briefly allowing spam, and the honeypot still applies.