Skip to content

QR studio

At /app/qr, generate table codes by number — a venue can have at most 200 live table codes at once, and a number that already has a code is skipped rather than duplicated. Pickup and delivery each get a single code, created automatically once you turn that context on at Links, delivery and follow us.

Each venue has one QR design shared by every code: a frame style (card, plain or tent), colors either drawn from your theme or set manually, whether the logo shows, whether the table number prints on the card, and the call-to-action text for table and pickup codes, in both languages. When the design uses theme colors, a contrast and darkness check runs automatically and falls back to black on white if your theme’s colors wouldn’t scan reliably.

Download any code as a PNG or SVG, composed on your own device with the fonts and logo inlined so it prints crisply. The print sheet at /app/qr/print lays out a batch of codes for your browser’s own “Save as PDF” — there’s no separate PDF export on the server.

What a code encodes, and why you never reprint

Section titled “What a code encodes, and why you never reprint”

Every printed code encodes {origin}/q/{code} — a short, permanent link, not the menu URL itself. Scanning it redirects to the menu with ?t={n} for a table or ?ctx=pickup / ?ctx=delivery, resolved fresh on every scan. That means renumbering a table, renaming your venue, or changing your slug never invalidates a code already printed and taped down — only the redirect target changes.

Each redirect records a scan, shown in the studio as a count over the last 30 days plus an all-time last-scan date. Scans only count while visitor analytics is on for the venue; while it’s off, every code reads zero scans, so a code that’s actually in daily use can look unused. Deleting a code that was scanned in the last 30 days is refused unless you force it through, and while analytics is off the studio warns that the scan count can’t be trusted before it lets you force a delete.

Print codes for tables 1 through 12

calls generate_qr with kind: 'table' and table_numbers: [1, 2, ..., 12] — up to 200 numbers in one call, and any that already have a code come back in skipped. Add dry_run: true to see what would be created first.