# How to Build a Product Catalog in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 25-30 min
- Compatibility: All Bubble plans
- Last updated: March 2026

## TL;DR

A product catalog in Bubble uses a Product Data Type displayed in a Repeating Group with category filters, price sorting, and a grid/list view toggle. This tutorial covers designing the product data model, building the catalog page with filter sidebar and product grid, adding sorting by price and date, implementing a view toggle between grid and list layouts, and creating dynamic product detail pages.

## Overview: Product Catalog in Bubble

This tutorial shows you how to build a complete product catalog page with category browsing, filtering, sorting, and product detail views. The approach works for any product-based app from e-commerce to SaaS feature showcases.

## Before you start

- A Bubble app on any plan
- A Product Data Type with sample records
- Basic understanding of Repeating Groups and data sources
- Familiarity with custom states and conditional formatting

## Step-by-step guide

### 1. Design the product data model

Go to the Data tab and create a 'Product' Data Type with fields: name (text), description (text), price (number), category (text or Option Set), image (image), images (list of images for gallery), is_featured (yes/no), stock_status (text — in stock/out of stock), and rating (number). Create an Option Set called 'ProductCategory' with options for your categories. Add 10-20 sample products across different categories for testing.

**Expected result:** A Product Data Type with sample data ready for the catalog display.

### 2. Build the catalog layout with filter sidebar

Create a page with two columns: a filter sidebar (250px) on the left and the product grid on the right. In the sidebar, add a Repeating Group of type ProductCategory (Option Set) showing all categories as clickable items. Create a custom state on the page called 'selected_category'. When a category is clicked, set this state to the clicked category. Add a 'Clear filters' link that resets the state to empty. Also add a price range using two Inputs for min and max price.

**Expected result:** A sidebar displays category filters and price range inputs that control the product display.

### 3. Display products in a grid with sorting

Add a Repeating Group with type Product in the main content area. Set it to a grid layout with 3 columns on desktop. Set the data source to Do a Search for Product with constraints: category = selected_category (with Ignore empty constraints checked), price >= min price input, price <= max price input. Add sorting controls above the grid: a Dropdown with options 'Price: Low to High', 'Price: High to Low', 'Newest First'. Use a custom state 'sort_order' and apply dynamic sorting to the search. Inside each cell, display the product image, name, price formatted as currency, and a category badge.

**Expected result:** Products display in a responsive grid with working category, price, and sort filters.

### 4. Add grid/list view toggle

Add two icon buttons above the product grid: a grid icon and a list icon. Create a custom state 'view_mode' (text, default 'grid'). When grid icon is clicked, set view_mode to 'grid'. When list icon is clicked, set view_mode to 'list'. Add two Repeating Groups: one configured as a 3-column grid and one as a single-column list. Set visibility conditions: grid RG visible when view_mode is 'grid', list RG visible when view_mode is 'list'. Both use the same data source. The list view shows a wider layout with image on the left and description on the right.

**Expected result:** Users can toggle between grid and list views of the product catalog.

### 5. Create dynamic product detail pages

Create a new page called 'product' with type Product. This makes it a dynamic page that receives a Product record via URL. On this page, display the product image gallery using a Repeating Group of the product's images list, the product name as a large heading, price, full description, category, stock status, and an Add to Cart or Contact button. Set up navigation from the catalog: when a product card is clicked, use Go to page → product and send the current cell's Product as the data. The URL will include the product's unique ID automatically.

> Pro tip: Set the page's SEO title to the product name dynamically for better search engine visibility of individual product pages.

**Expected result:** Clicking a product in the catalog navigates to a detailed product page with full information and image gallery.

## Complete code example

File: `Workflow summary`

```text
PRODUCT CATALOG SUMMARY
=====================================

DATA MODEL:
  Product: name, description, price, category,
    image, images (list), is_featured,
    stock_status, rating
  ProductCategory: Option Set with categories

CATALOG PAGE LAYOUT:
  Left sidebar (250px):
    Category list (RG of Option Set)
    Price range (min/max inputs)
    Clear filters link
  Right content:
    Sort dropdown + view toggle icons
    Product grid/list Repeating Group

CUSTOM STATES:
  selected_category (ProductCategory)
  sort_order (text): price_asc, price_desc, newest
  view_mode (text): grid, list

PRODUCT SEARCH:
  Do a Search for Product
    category = selected_category
    price >= min_price
    price <= max_price
    Ignore empty constraints: yes
  Sorted by: dynamic based on sort_order
  Paginated: 12-20 items per page

PRODUCT CARD (GRID):
  Image (fit, 1:1 ratio)
  Name (truncated to 2 lines)
  Price (formatted as currency)
  Category badge
  Click → Go to product page

PRODUCT DETAIL PAGE:
  Type: Product (dynamic page)
  Image gallery (RG of images)
  Name, price, description
  Category, stock status
  Add to Cart / Contact button
  SEO title = Product's name
```

## Common mistakes

- **Loading all products without pagination** — Displaying hundreds of products at once causes slow page loads and poor user experience Fix: Paginate the Repeating Group to 12-20 items per page with navigation controls
- **Using :filtered for category filtering instead of search constraints** — Client-side filtering downloads all products before filtering, wasting bandwidth and WUs Fix: Use category as a search constraint in Do a Search For with Ignore empty constraints enabled
- **Not setting up the product detail page as a dynamic page type** — Without the page type set to Product, you cannot access the product's data directly and must pass it through URL parameters Fix: Set the page type to Product in the page properties, then send the product via Go to page action

## Best practices

- Use Option Sets for product categories for instant filtering without database queries
- Paginate products to 12-20 items for fast loading
- Optimize product images with appropriate sizes for grid thumbnails
- Set SEO meta tags dynamically on product detail pages
- Add a featured products section at the top of the catalog
- Use the search constraint approach for all filters instead of client-side :filtered
- Cache filter states in URL parameters so users can share filtered views

## Frequently asked questions

### How many products can a Bubble catalog handle?

With proper pagination and search constraints, a Bubble catalog can handle thousands of products. Performance typically remains good up to 30,000-50,000 records with optimization.

### Can I add product variants like size and color?

Yes. Create a ProductVariant Data Type linked to Product with fields for size, color, price override, and stock. Display variants as selectable options on the detail page.

### How do I handle product images efficiently?

Use Imgix URL parameters to serve thumbnails at 400px width in the grid and full-size images only on the detail page. This dramatically reduces page weight.

### Can I make the catalog URL-filterable for sharing?

Yes. Store filter states in URL parameters using the Go to page action with Send more parameters. Read them on page load with Get data from page URL to restore the filter state.

### How do I add a 'New' or 'Sale' badge to products?

Add conditional badges on product cards: show 'New' when Created Date is within the last 7 days, show 'Sale' when the product has a sale_price field that is less than the regular price.

### Can RapidDev help build a product catalog?

Yes. RapidDev can build complete product catalog systems in Bubble including advanced filtering, search, variant management, and integration with payment processing.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/create-a-product-catalog-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/create-a-product-catalog-in-bubble
