Back to Projects
WebSaaSFull-Stack

VideoMenu — QR Video Menu SaaS

Live Preview
FFavorites
Classic
Signature
EN

Favorites

Banana Matcha Latte

TRY 255.00

Spanish Latte

TRY 240.00

Espresso Tonic

TRY 220.00

Pistachio Quattro Latte

TRY 265.00

Tech Stack

Next.js 14TypeScriptSupabasePostgreSQLTailwind CSSshadcn/uiFramer MotionZodDeepL APIEdge CDNVercel

Overview

VideoMenu is a production SaaS for restaurants: each business gets a QR-code-driven digital menu where dishes and sections are presented as short autoplay videos instead of static photos. Two visual templates ("Classic" and "Spotlight") render the same data differently, so a restaurant can pick the look it wants. The product has two surfaces over one database — a public menu scanned via QR, and a private dashboard where owners and super-admins manage content. All UI copy is bilingual (Turkish default, English).

Built on Next.js 14 App Router with server components by default, Supabase (Postgres + Auth + Storage) for data and media, and a template registry abstraction that decouples menu routes from rendering. Menu media are short videos served from Supabase Storage and fronted by an optional edge CDN pull-zone that cuts storage egress and speeds up delivery, with lazy, intersection-driven playback and a capped playback queue to limit simultaneous decodes on mobile. Menu content is stored bilingually with optional DeepL machine translation, multi-tenant access is enforced with Postgres RLS, and the whole thing is deployed on Vercel at video-menus.com.

Challenges

  • Playing many short videos at once on mobile without janking — uncontrolled autoplay would overwhelm the device's decoders
  • Serving one menu in two completely different visual templates from the same database without forking the route logic
  • Multi-tenancy: super-admins managing many restaurants while owners stay scoped to their own, enforced safely on the server
  • Serving video-heavy menus without runaway storage egress and bandwidth costs as traffic grows

Solutions

  • Decoupled a wide IntersectionObserver buffer ring from a ratio-ranked playback queue that caps how many clips actually play (MAX_PLAYING), with first-frame posters so cards paint instantly
  • Built a template registry where a restaurant's menu_template column selects the renderer; routes never import template components directly
  • Used Supabase Auth + Postgres RLS with a server-side dashboard context resolver and a service-role admin client for super-admin-gated owner provisioning
  • Routed all menu media through an edge CDN pull-zone in front of Supabase Storage, rewriting URLs on the server read path to cut egress and serve videos from the edge
1