/library / template-vertical-restaurant-menu
templateVertical (industry)

Restaurant menu + online ordering (Square integration)

A site for a single restaurant. Live menu (synced from Square Catalog), online ordering for pickup, reservation link, locations + hours, real food photography. Built for restaurants that DON'T want to give 30% to DoorDash.

use whenYou're building for a restaurant owner sick of 30% delivery fees. The site routes orders direct to Square; the kitchen prints them on the Square hardware they already own.

May 4, 20262,120 bytesrestaurantsquareorderingmenuhospitality

[Restaurant Name] · Menu + Ordering

A restaurant marketing + ordering site. Menu syncs from Square so the owner edits once. Orders route to the kitchen via Square. The site charges nothing extra.

Source of truth

Square is the source for menu items, prices, modifiers, and inventory. The site reads Square Catalog at build time and caches. Orders POST to Square Orders API. Reservations link out to OpenTable or Resy.

Tech stack

Next.js 15 (App Router) + React + Tailwind v4. Square Web SDK for the payment card form, Square Orders API for order creation. Cloudinary for food photography. Resend for confirmation emails. ISR (Incremental Static Regen) for menu pages, revalidating every 5 minutes.

Deploy

git push origin main. Vercel auto-deploys. Square webhook configured to revalidate the menu page on catalog updates.

File map

  • app/page.tsx home: hero photo, today's specials, ordering CTA, location/hours
  • app/menu/page.tsx full menu, categorized, sourced from Square Catalog
  • app/order/page.tsx cart + checkout
  • app/order/confirmation/[orderId]/page.tsx post-order screen
  • app/locations/[slug]/page.tsx per-location page (hours, address, photos, map)
  • app/api/order/route.ts POST -> Square Orders + Square Payments
  • app/api/webhook/square/route.ts Square webhook: catalog.updated triggers revalidation
  • lib/square.ts Square SDK client
  • lib/cart.ts localStorage cart with modifier support

.env keys

  • SQUARE_ACCESS_TOKEN
  • SQUARE_LOCATION_ID
  • SQUARE_WEBHOOK_SIGNATURE_KEY
  • SQUARE_ENVIRONMENT production | sandbox
  • NEXT_PUBLIC_SQUARE_APPLICATION_ID (Web SDK)
  • RESEND_API_KEY
  • RESEND_FROM_EMAIL

Hard rules

  • Menu prices come from Square. Never hardcode a price in JSX.
  • Cart modifiers map to Square modifier IDs. Test that a "no cilantro" modifier reaches the printer.
  • Pickup-only for v0. Delivery is a different beast (DoorDash Drive integration is a separate template).
  • Tax + tip computed via Square (calculateOrder), never client-side. State sales tax + alcohol rules are complex.
  • Photos of food are real, shot tight, well-lit. Stock photos of "delicious burger" kill orders.
  • Confirmation page shows estimated ready time + pickup instructions (the exact door, parking note).
  • Square webhook signature is verified before any state change.

Recent significant changes

  • 2026-05-04: Scaffolded. Locked: Square direct (the restaurant already owns the hardware), pickup-only v0, no third-party marketplace integration (the whole point).

Next session: start here

  1. Get Square access from the restaurant. Sandbox first, production later.
  2. Sync menu: confirm square.catalog.searchCatalogItems returns the actual items.
  3. Build cart + checkout flow with sandbox cards.
  4. Test a real $1 order end-to-end. Confirm receipt prints in the kitchen.
  5. Set up Square webhook for catalog updates -> Next.js revalidation.

Get the next CLAUDE.md in your inbox.

One new template every week, plus occasional case studies.