Build comparison lists in Bubble by letting users add items to a compare list using custom states or a CompareList data type, then displaying selected items side-by-side in a horizontal Repeating Group with attributes aligned in rows. Highlight the best value in each row for quick decision-making.
Overview: Creating Comparison Lists in Bubble
This tutorial shows you how to build a product or feature comparison interface in Bubble. Users can select items to compare from a listing page, view them side-by-side with attributes aligned in rows, and see the best value highlighted in each category. This is essential for e-commerce, SaaS pricing pages, or any app where users need to evaluate options.
Prerequisites
- A Bubble account with an existing app
- A data type with comparable attributes (e.g., Product with price, rating, features)
- Basic understanding of Bubble Repeating Groups and custom states
- Familiarity with conditional formatting
Step-by-step guide
Set up the compare list mechanism
Set up the compare list mechanism
On your product listing page, add a Custom State on the page called compare_list (type: list of Products). When a user clicks a Compare checkbox or button on a product card, add the product to this list: Set state of Page — compare_list add Current cell's Product. To remove, use the remove operator. Limit the list to 3-4 items by adding an Only when condition: Page's compare_list:count < 4.
Pro tip: Show a floating bar at the bottom of the page displaying the number of selected items and a Compare Now button that navigates to the comparison view.
Expected result: Users can add up to 4 products to a comparison list stored in a page custom state.
Build the side-by-side comparison layout
Build the side-by-side comparison layout
Create a comparison section (or a separate page). Add a Repeating Group with type Product, layout set to horizontal (Row), data source: Page's compare_list. Each cell displays the product image, name, and key attributes in a vertical Column layout. Ensure all cells have identical heights by using fixed-height Groups for each attribute row. This creates the side-by-side column effect.
Expected result: Selected products appear in horizontal columns with attributes aligned vertically.
Add attribute rows with labels
Add attribute rows with labels
To the left of the horizontal Repeating Group, add a fixed-width column with labels for each attribute: Price, Rating, Category, Features, etc. Align these labels vertically to match the attribute positions in each comparison cell. Each attribute in the Repeating Group cell should be at the same vertical position as its label. Use Groups with fixed heights to maintain alignment.
Expected result: Attribute labels on the left align with corresponding values in each product column.
Highlight the best value in each row
Highlight the best value in each row
Add conditionals to highlight winning values. For Price (lowest is best): When Current cell's Product's price = Page's compare_list:each item's price:min, change the text color to green and make it bold. For Rating (highest is best): When Current cell's Product's rating = compare_list:each item's rating:max, apply the same highlight. Repeat for each comparable attribute with appropriate min/max logic.
Expected result: The best value in each comparison row is highlighted in green bold text.
Add remove and clear functionality
Add remove and clear functionality
In each comparison column header, add an X button to remove that product: Set state compare_list remove Current cell's Product. Add a Clear All button above the comparison that empties the list: Set state compare_list to empty. When the list is empty, show a message like Select products to compare with links back to the catalog page. For sophisticated comparison tools with weighted scoring, consider working with RapidDev.
Expected result: Users can remove individual items or clear the entire comparison, with an empty state message.
Complete working example
1COMPARISON LISTS — WORKFLOW SUMMARY2=====================================34PAGE CUSTOM STATE:5 compare_list (list of Products, default empty)67CATALOG PAGE:8 Each product card:9 - Checkbox/Button: Add to Compare10 Visible when: compare_list doesn't contain this Product11 - Button: Remove from Compare12 Visible when: compare_list contains this Product13 Floating Compare Bar:14 Visible when: compare_list:count > 015 Text: "Comparing X items"16 Button: Compare Now → navigate to comparison view1718WORKFLOW: Add to compare19 Event: Button Add to Compare is clicked20 Only when: compare_list:count < 421 Action: Set state compare_list add Current cell's Product2223WORKFLOW: Remove from compare24 Event: Button Remove is clicked25 Action: Set state compare_list remove Current cell's Product2627COMPARISON VIEW:28 Layout:29 - Left column: attribute labels (fixed width)30 - Horizontal Repeating Group (type: Product)31 Data source: compare_list32 Each cell (Column layout):33 - Product image34 - Product name + Remove X35 - Price (conditional: green when = min)36 - Rating (conditional: green when = max)37 - Category38 - Feature list3940CONDITIONALS (per cell):41 Price text:42 When this Product's price = compare_list's prices:min43 → color green, bold44 Rating text:45 When this Product's rating = compare_list's ratings:max46 → color green, boldCommon mistakes when building comparison lists in Bubble
Why it's a problem: Not limiting the number of items in the comparison list
How to avoid: Add an Only when condition limiting the list to 3-4 items and show a message when the limit is reached.
Why it's a problem: Using a database data type instead of custom state for the compare list
How to avoid: Use a page Custom State (list type) for the comparison. It resets on page reload and costs zero workload units.
Why it's a problem: Not aligning attribute rows across columns
How to avoid: Use fixed-height Groups for each attribute row in the Repeating Group cells so all columns align vertically.
Best practices
- Limit comparisons to 3-4 items for readability
- Use custom states for temporary compare lists to avoid database operations
- Align all attribute rows at the same height across columns
- Highlight the best value in each row with color and bold text
- Show a floating bar on the catalog page with the compare count and action button
- Add a clear all button for quick reset
- Handle the empty state with a helpful message linking back to the catalog
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I am building a product comparison feature in Bubble.io. Users should add items to a compare list from the catalog, then see them side-by-side with the best values highlighted. How do I use custom states for the list and build the comparison layout?
Build a product comparison feature. Add a compare list using a page custom state (list of Products, max 4). Show a floating compare bar. Create a side-by-side comparison view with attribute rows and highlight the best price and rating.
Frequently asked questions
Can I persist the comparison list across page reloads?
Custom states reset on reload. To persist, save the selected product IDs as URL parameters or store the list in a database field on the User.
How do I handle products with different sets of attributes?
Use a consistent attribute set for all products. For missing values, display N/A with gray text so the row alignment is maintained.
Can I compare more than 4 items?
Technically yes, but horizontal layouts become unusable beyond 4 items on most screens. Consider a scrollable comparison table for larger sets.
Does the comparison work on mobile?
A horizontal layout with 3-4 columns is tight on mobile. Consider a tabbed view on small screens where users swipe between products.
Can RapidDev help build advanced comparison tools?
Yes. RapidDev specializes in Bubble development and can build sophisticated comparison tools with weighted scoring, user-defined criteria, and exportable comparison reports.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation