# How to build a food delivery platform in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 45-60 min
- Compatibility: Growth plan+ (backend workflows needed for order processing)
- Last updated: March 2026

## TL;DR

Building a food delivery platform in Bubble involves creating Data Types for restaurants, menus, orders, and delivery drivers, then building customer-facing ordering pages, a restaurant management dashboard, and a delivery tracking system. This tutorial covers the full architecture from restaurant onboarding through order fulfillment and real-time status updates.

## Overview: Building a Food Delivery Platform in Bubble

This tutorial walks through building a food delivery platform similar to UberEats or DoorDash in Bubble. You will create the database architecture, build customer-facing pages for browsing restaurants and placing orders, design a restaurant dashboard for managing menus and incoming orders, and implement a delivery tracking system. While a production platform would require additional optimization, this gives you a solid MVP to test your market.

## Before you start

- A Bubble account on a Growth plan or higher
- Stripe plugin installed for payment processing
- Basic understanding of Bubble Data Types and workflows
- Familiarity with Repeating Groups and page navigation

## Step-by-step guide

### 1. Design the database schema for the platform

Go to the Data tab and create these Data Types: Restaurant (name, description, address, logo, cuisine_type, is_open, owner — type User, delivery_radius — number, rating — number). Menu_Item (restaurant — type Restaurant, name, description, price — number, image, category — text, is_available — yes/no). Order (customer — User, restaurant — Restaurant, items — list of Order_Item, status — text: pending/confirmed/preparing/ready/delivering/delivered, subtotal, delivery_fee, total, delivery_address, driver — User, created_at — date). Order_Item (menu_item — Menu_Item, quantity — number, special_instructions — text, line_total — number). Driver_Profile (user — User, is_available — yes/no, current_location — geographic address).

**Expected result:** Five Data Types with all fields created, forming the foundation of the food delivery platform.

### 2. Build the restaurant browsing and menu pages

Create an 'index' page with a Search Input for restaurant name or cuisine, and a Repeating Group displaying Restaurants where is_open is yes. Each cell shows the restaurant logo, name, cuisine type, rating, and estimated delivery time. When a restaurant card is clicked, navigate to a 'restaurant' page (type: Restaurant). On the restaurant page, display the restaurant header (logo, name, rating, delivery info) and a Repeating Group of Menu_Items grouped by category. Each item shows the image, name, description, and price with an 'Add to Cart' button.

**Expected result:** Users can browse open restaurants and view their menus organized by category.

### 3. Implement the shopping cart using custom states

On the restaurant page, create a custom state on the page called cart_items (list of Order_Items). When the user clicks 'Add to Cart', create a new Order_Item (not saved to database yet — use custom state) and add it to the cart_items list. Display a cart sidebar or popup showing all cart_items in a Repeating Group with item name, quantity, special instructions input, and line total. Add quantity +/- buttons and a Remove button. Calculate the subtotal dynamically using cart_items:each item's line_total:sum. Add a 'Proceed to Checkout' button that navigates to the checkout page.

> Pro tip: Store cart items in custom states (not the database) until the user places the order — this avoids creating orphan records for abandoned carts.

**Expected result:** A functional cart that lets users add items, adjust quantities, and see a running subtotal.

### 4. Create the checkout and order placement flow

Create a 'checkout' page showing the order summary, delivery address input (using a Google Places autocomplete plugin for address autofill), and a payment button. When the user clicks 'Place Order': create the Order record with status 'pending' and all cart data, create Order_Item records for each cart item, process payment via Stripe Checkout or Stripe Elements, and on payment success, update the Order status to 'confirmed'. Send an email notification to the restaurant owner. Schedule a backend workflow to auto-cancel orders not confirmed by the restaurant within 10 minutes.

**Expected result:** Users can enter a delivery address, pay via Stripe, and place an order that notifies the restaurant.

### 5. Build the restaurant owner dashboard

Create a 'restaurant-dashboard' page restricted to users with a restaurant owner role. Display incoming orders in a Repeating Group filtered by restaurant = Current User's Restaurant and status = 'confirmed'. Each order card shows the customer name, items ordered, total, and delivery address. Add 'Accept' and 'Reject' buttons. Accept changes status to 'preparing'. When food is ready, a 'Ready for Pickup' button changes status to 'ready'. Add a menu management section where the owner can add, edit, and toggle availability of Menu_Items.

**Expected result:** Restaurant owners can view incoming orders, accept or reject them, mark them as ready, and manage their menu.

### 6. Implement delivery status tracking

Create a 'track-order' page (type: Order) that displays the order status with a visual progress indicator showing stages: Confirmed → Preparing → Ready → Delivering → Delivered. Use conditional formatting to highlight the current stage. The page auto-updates because Bubble's database searches update via WebSocket. When a driver accepts the order (status changes to 'delivering'), show the driver's name. For a simplified tracking view, display the estimated delivery time based on order creation time plus the restaurant's average preparation time. A backend workflow can send SMS notifications (via Twilio) at each status change.

**Expected result:** Customers can track their order status in real time with visual progress indicators and notifications.

## Complete code example

File: `Workflow summary`

```text
FOOD DELIVERY PLATFORM SUMMARY
===============================

DATA TYPES:
  Restaurant: name, description, address, logo, cuisine_type,
    is_open, owner (User), delivery_radius, rating
  Menu_Item: restaurant, name, description, price, image,
    category, is_available
  Order: customer (User), restaurant, items (list Order_Item),
    status, subtotal, delivery_fee, total, delivery_address,
    driver (User), created_at
  Order_Item: menu_item, quantity, special_instructions, line_total
  Driver_Profile: user, is_available, current_location

PAGES:
  index — Browse restaurants
  restaurant — View menu, add to cart
  checkout — Address, payment, place order
  track-order — Real-time status tracking
  restaurant-dashboard — Owner order management
  driver-dashboard — Accept and deliver orders

CUSTOMER FLOW:
  Browse → Select restaurant → Add items to cart
  → Checkout (address + payment) → Track order

RESTAURANT FLOW:
  View incoming orders → Accept/Reject
  → Mark preparing → Mark ready for pickup

DRIVER FLOW:
  View available orders → Accept delivery
  → Pick up from restaurant → Mark delivered

ORDER STATUS SEQUENCE:
  pending → confirmed → preparing → ready → delivering → delivered

KEY WORKFLOWS:
  Place Order: Create Order + Order_Items → Stripe payment
    → Update status to 'confirmed' → Email restaurant
  Accept Order: Status → 'preparing'
  Ready: Status → 'ready' → Notify available drivers
  Driver Accept: Status → 'delivering', assign driver
  Delivered: Status → 'delivered' → Email receipt
  Auto-cancel: Backend workflow, 10 min timeout for unconfirmed
```

## Common mistakes

- **Saving cart items to the database before the order is placed** — Users who abandon their cart create orphan Order_Item records that clutter your database and consume storage Fix: Store cart items in custom states until checkout is complete, then create database records only when the order is confirmed
- **Not implementing order timeout for unconfirmed orders** — If a restaurant does not respond, the customer waits indefinitely with no feedback Fix: Schedule a backend workflow that auto-cancels orders not confirmed within 10 minutes and notifies the customer
- **Using a single status field without status history** — You lose visibility into how long each stage took, making it impossible to identify bottlenecks Fix: Create a Status_Change Data Type that logs each status transition with a timestamp for analytics

## Best practices

- Store cart items in custom states until the order is placed to avoid orphan records
- Implement auto-cancel timeouts for orders not confirmed by restaurants
- Use backend workflows for order status changes so they persist even if the browser closes
- Send notifications (email or SMS) at each order status change
- Log status changes with timestamps for performance analytics
- Use Privacy Rules to restrict restaurant dashboard data to the restaurant owner
- Add address validation at checkout to prevent undeliverable orders

## Frequently asked questions

### Can I build a full food delivery app like UberEats in Bubble?

You can build an MVP with core features: restaurant listings, ordering, payment, and status tracking. For production scale with thousands of concurrent orders, you may need to optimize heavily or move some processing to external services.

### How do I handle payment splits between the platform and restaurants?

Use Stripe Connect with the Express account type. Each restaurant gets a connected Stripe account. When a customer pays, the platform takes a commission and transfers the rest to the restaurant automatically.

### How do I show estimated delivery time?

Calculate it as the restaurant's average preparation time plus an estimated transit time based on distance. Store average prep times on the Restaurant Data Type and update them based on actual order completion data.

### Can I add a real-time map for delivery tracking?

Yes. Use a map plugin (Google Maps) on the tracking page and update the driver's location via a recurring backend workflow or the driver's app updating their location field.

### How do I handle restaurant operating hours?

Add opening_time and closing_time fields (date/time) to the Restaurant Data Type for each day of the week. Use a conditional check before showing the restaurant as available.

### Can RapidDev help build a food delivery platform in Bubble?

Yes. RapidDev can build complete food delivery platforms including multi-restaurant support, real-time order tracking, driver assignment, payment processing with Stripe Connect, and admin dashboards.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/build-a-food-delivery-platform-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/build-a-food-delivery-platform-in-bubble
