Sub-100ms Digital Menus: Bypassing Aggregator Commissions with Next.js & WhatsApp Dispatch
How we engineered a high-converting direct-ordering PWA for Sassy Tandoor with Next.js App Router, edge caching, and automated WhatsApp Cloud API dispatch, slashing 30% aggregator commission leakage.
The 30% Delivery App Tollbooth in the Indian F&B Market
In the Indian hospitality and quick-service restaurant industry, food delivery aggregators like Zomato and Swiggy operate what effectively amounts to a 28% to 34% revenue tollbooth. For dine-in patrons sitting at tables and repeat neighborhood customers ordering dinner from home, forcing orders through third-party platforms destroys net profit margins.
When Sassy Tandoor approached us, their challenge was crystal clear: build an independent direct-ordering digital channel at `sasssytandoor.store` that would match the speed and delight of consumer delivery apps, eliminate aggregator fees, and establish a direct customer relationship over WhatsApp.
However, consumer psychology in food ordering is unforgiving. A customer scanning a tabletop QR code on a crowded restaurant terrace with weak cellular connectivity will not wait five seconds for a heavy web app to load, nor will they download a native app or complete a tedious password registration form. If the digital menu is not instantaneously interactive, they call the waiter for a physical laminated menu.
The Conversion Equation: In hospitality web applications, bounce rate is directly correlated with First Contentful Paint. Every 100ms delay in menu rendering costs an estimated 7% in customer order completion rates.
Next.js App Router and Edge Caching for Instant Menus
To achieve sub-100ms initial page delivery, we rejected heavy client-rendered component architectures in favor of Next.js App Router with Static Site Generation (SSG) combined with on-demand Incremental Static Regeneration (ISR).
The entire menu catalog—complete with categories, item descriptions, spice-level selectors, and pricing—is pre-rendered into static HTML at build time and cached globally across edge points of presence. When a customer scans the table QR code, the browser receives an edge-cached response within 85 milliseconds.
Menu changes (such as 86'ing a sold-out tandoori specialty or modifying daily dessert availability) trigger an on-demand revalidation webhook from our Supabase admin panel, refreshing the edge cache globally within 300 milliseconds without requiring a full rebuild.
import { getMenuItems } from "@/lib/menu";
import { MenuGrid } from "@/components/menu/MenuGrid";
import { CartDrawer } from "@/components/cart/CartDrawer";
// Static edge generation with on-demand tag revalidation
export const revalidate = false; // Cached indefinitely until on-demand webhook fires
export default async function MenuPage() {
const categories = await getMenuItems();
return (
<main className="mx-auto max-w-4xl px-4 py-8">
<header className="mb-8 text-center">
<h1 className="font-display text-4xl font-medium tracking-tight text-charcoal">
Sassy Tandoor Kitchen Menu
</h1>
<p className="mt-2 text-sm text-ink-muted">
Fresh tandoori breads, clay-oven kebabs, and authentic curries.
</p>
</header>
{/* Instant, client-hydrated reactive order drawer */}
<MenuGrid categories={categories} />
<CartDrawer />
</main>
);
}Zero-Friction Client State and Offline Cart Persistence
Traditional web shops make asynchronous network calls every time a user adds an item to their shopping cart. In a restaurant with patchy Wi-Fi or basement cellular coverage, network latency produces sluggish UI feedback, double-clicks, and phantom order states.
Our cart architecture is entirely local and synchronous. We maintain cart state in a lightweight React store backed by browser `localStorage`. When a diner taps '+ Add', the cart quantity counter animates immediately with zero milliseconds of network latency.
If the customer's phone switches from Wi-Fi to 5G or the browser tab is accidentally reloaded, the cart state remains 100% intact. Network requests are deferred exclusively until the final checkout submission.
Automated WhatsApp Cloud API Dispatch and Kitchen Integration
Rather than forcing users to download an app or check their email for delivery tracking, we anchored the fulfillment workflow around the channel where 95%+ of Indian smartphone users communicate daily: WhatsApp.
When the customer confirms their order, a Next.js Server Action executes an atomic multi-step pipeline:
1. Validates the order items, calculating taxes and discounts on the server.
2. Inserts an immutable order record into Supabase PostgreSQL.
3. Fires a webhook to Meta's WhatsApp Business Cloud API, instantly messaging the customer an order confirmation with live status tracking.
4. Emits a real-time event to the kitchen display tablet (KDS), triggering an audible chime and printing an automated KOT (Kitchen Order Ticket) on the kitchen thermal printer.
export async function submitOrder(cartPayload: OrderPayload) {
// 1. Server-side validation against tamper-proof database prices
const verifiedOrder = await validateCart(cartPayload);
// 2. Insert into Supabase with atomic transaction
const { data: order, error } = await supabase
.from("orders")
.insert({
customer_name: verifiedOrder.customerName,
customer_phone: verifiedOrder.customerPhone,
table_number: verifiedOrder.tableNumber,
total_amount: verifiedOrder.totalAmount,
items: verifiedOrder.items,
status: "confirmed"
})
.select()
.single();
if (error || !order) throw new Error("Order creation failed");
// 3. Dispatch automated WhatsApp notification via Meta Cloud API
const whatsappPayload = {
messaging_product: "whatsapp",
to: `91${verifiedOrder.customerPhone}`,
type: "template",
template: {
name: "order_confirmation_v2",
language: { code: "en" },
components: [
{
type: "body",
parameters: [
{ type: "text", text: verifiedOrder.customerName },
{ type: "text", text: `#${order.id.slice(-6).toUpperCase()}` },
{ type: "text", text: `₹${verifiedOrder.totalAmount}` },
{ type: "text", text: "15-20 minutes" }
]
}
]
}
};
await fetch(`https://graph.facebook.com/v20.0/${process.env.WHATSAPP_PHONE_ID}/messages`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.WHATSAPP_SYSTEM_TOKEN}`,
"Content-Type": "application/json"
},
body: JSON.stringify(whatsappPayload)
});
return { success: true, orderId: order.id };
}Business Impact: Margins Restored and 100% Customer Retention
The platform is live in active production at `sasssytandoor.store`. By shifting direct dine-in QR orders and repeat neighborhood deliveries to their proprietary platform, Sassy Tandoor eliminated thousands of rupees in monthly aggregator commission leakage.
Furthermore, because orders flow directly through their own system rather than an aggregator's walled garden, Sassy Tandoor owns their customer data. They can send automated WhatsApp re-engagement offers for weekend specials and festive menus, driving customer lifetime value (LTV) far higher than any aggregator listing could ever deliver.
Read more in the Sassy Tandoor Case Study or see our Web Applications practice for high-performance commerce systems.
Written By
Nikhil Anand
Principal Software Engineer & Technical Architect. Building high-performance web applications, offline-first desktop software, and enterprise data architectures for ambitious companies across India and globally.
Need an architecture like this for your product?
I design and build resilient, high-speed software systems tailored to your business operations. Schedule an architecture review or discuss project specifications directly.