Gelateria Brina: the website of a gelato shop that shows today's flavours live

Demo website of a fictional gelato shop in Turin. The gelato maker marks from her phone which flavours are in and which have sold out, and the site's display, drawn in code tub by tub, updates live with the time of the last change. With the flavour catalogue, allergens, opening hours and an admin panel you can try without an account.

**Gelateria Brina doesn't exist**: it's a made-up artisan gelato shop in Turin, and the gelato maker, the flavours, the recipes and the photos are invented; the site says so at the top of every page. Everything else is real: the live display, the opening hours, the allergen register and the admin panel, built as they would be for a real business.

**What it does**

- **Today's flavours, live.** Instead of a photo there's the counter, drawn in SVG by code: each tub in its flavour's colour, with a name tag. When a flavour sells out, its tub empties on every open screen in under a second, and the display reads "Updated at 15:42". - **The panel on the phone.** The gelato maker taps big switches: this flavour is in, this one isn't, this one has sold out. Every tap goes live straight away and can be undone for eight seconds. - **Allergens.** Ingredients with allergens in bold, the 14 required by EU law, a register to print for the shop, and no "free from" filters, which would read like a guarantee. - **The rest.** Seasonal flavours, opening hours with the winter break and a calculated "open now", a hand-drawn map, cookie-free visitor statistics and 13 photos generated on my computer's GPU.

**Visitors can try the admin panel** without an account: they sign in as "Guest", follow three things to try and, on a computer, watch the site change next to the panel at every tap. Their changes stay in their browser, where the same server logic runs on a copy of the data; an automated test checks, route by route, that it answers like the server. And so the display never sits still, a demo day prepares the counter at opening time and sells out a few flavours.

**The hard part** is never pretending to be up to date. If nobody has touched the counter today, the display says so: "these are last night's flavours". A sold-out flavour stays sold out until someone puts it back. And live updates have to hold up on a real server: events go through nginx without being held back, a ping every 25 seconds keeps the connection alive, and if the live channel can't open, the page asks for the state every minute. The home page ships 99 KB of JavaScript and doesn't shift while it loads.

Vue 3 and TypeScript, Fastify and MongoDB, shared Zod schemas; every change goes through 165 automated tests and reaches my server with a GitHub Action.

Design, full-stack development and deployment · 2026

Vue.js, Fastify, MongoDB, TypeScript, Z-Image-Turbo

View the site

Andrea Coppetta