Build a content recommendation system in Bubble by tracking user interactions (views, likes, saves), tagging content with categories, and using search constraints to find related items users have not seen yet. Display personalized 'Recommended for You' sections using Repeating Groups filtered by the user's interest profile, combining collaborative filtering signals with category-based matching.
Building a Content Recommendation System in Bubble
Content recommendations keep users engaged by showing them articles, products, or media they are likely to enjoy. This tutorial teaches you how to build a simple but effective recommendation engine in Bubble — tracking what users view and like, building interest profiles from their behavior, and serving personalized content suggestions. No machine learning required — just smart database queries and Bubble's native search capabilities.
Prerequisites
- A Bubble account with an app open in the editor
- Content stored in a Data Type (articles, products, or any content type)
- User authentication set up
- Basic familiarity with searches and Repeating Groups
Step-by-step guide
Set up content categories and user interaction tracking
Set up content categories and user interaction tracking
Ensure your content Data Type (e.g., 'Article') has a 'categories' field (list of texts or list of an Option Set 'Category'). Create a 'UserInteraction' Data Type with fields: user (User), content (Article), interaction_type (text: 'view', 'like', 'save', 'share'), timestamp (date). Also add a 'user_interests' field (list of texts) to the User Data Type to store accumulated interest categories.
Expected result: Data types are set up to track content categories and user interactions.
Log user interactions throughout the app
Log user interactions throughout the app
On your article/content detail page, add a 'Page is loaded' workflow: Create a new thing UserInteraction (user = Current User, content = Current Page Article, interaction_type = 'view', timestamp = Current date/time). When a user clicks a 'Like' button, create another UserInteraction with type 'like.' When they click 'Save,' create one with type 'save.' These interaction records form the basis of the recommendation engine — likes and saves carry more weight than views.
Pro tip: Add an 'Only when' condition to the view logging: 'Do a search for UserInteractions where user = Current User and content = Current Page Article and interaction_type = view:count is 0' to prevent logging duplicate views.
Expected result: Every content view, like, and save is recorded as a UserInteraction with the user and content reference.
Build the user interest profile from interactions
Build the user interest profile from interactions
Create a backend workflow called 'update_user_interests' that recalculates a user's interest profile. Search all UserInteractions where user = the target user and interaction_type is 'like' or 'save' (weighted interactions). Collect the categories from each interacted content item. Find the top 5 most frequent categories. Update the User's user_interests field with this list. Schedule this workflow to run after every like or save action, or run it daily via a scheduled workflow.
Expected result: Each user has an automatically-updated list of their top interest categories based on their behavior.
Create the recommendation search logic
Create the recommendation search logic
On your homepage or content feed page, add a Repeating Group for recommendations. Set Type of content to 'Article' and Data source to: 'Do a search for Articles' with constraints: categories contains list Current User's user_interests (matches any of the user's interests). Add an advanced filter: ':filtered' where This Article's unique id is not in 'Do a search for UserInteractions where user = Current User:each item's content's unique id' — this excludes content the user has already seen. Sort by Created Date descending to show newest first. Limit to 10 items.
Pro tip: The advanced filter is expensive on large datasets. For better performance, maintain a 'viewed_content' list field on the User and use it as a database constraint instead of the filtered operator.
Expected result: A 'Recommended for You' section shows content matching the user's interests that they have not yet viewed.
Add a fallback for new users with no interaction history
Add a fallback for new users with no interaction history
New users have no interests data, so the recommendation search returns nothing. Add a conditional on the Repeating Group: 'When Current User's user_interests:count is 0 → Data source = Do a search for Articles sorted by most liked (a popularity_score field or search UserInteractions grouped by content with count).' This shows popular content as a starting point. As the user interacts, personalized recommendations replace the popular defaults. Add a 'Trending' section that always shows high-engagement content regardless of personalization.
Expected result: New users see popular content, while returning users see personalized recommendations that improve over time.
Add feedback controls to improve recommendations
Add feedback controls to improve recommendations
On each recommended item in the Repeating Group, add small 'Not interested' and 'Show more like this' buttons. 'Not interested' creates a UserInteraction with type 'dismiss' and removes the content from the current view (using a custom state list of dismissed IDs to filter). 'Show more like this' creates a 'like' interaction, which feeds back into the interest profile. This feedback loop continuously improves recommendation quality as users interact with the suggestions.
Expected result: Users can actively improve their recommendations by providing positive and negative signals on suggested content.
Complete working example
1CONTENT RECOMMENDATION SYSTEM2===============================34Data Types:5 Article: title, body, categories (list of text), author,6 created_date, like_count, view_count7 UserInteraction: user (User), content (Article),8 interaction_type (view/like/save/dismiss),9 timestamp10 User (extended): user_interests (list of text)1112Interaction Logging:13 Page Load (article page):14 Only when: not already viewed by this user15 Create UserInteraction (user, content, 'view', now)16 17 Like Button Click:18 Create UserInteraction (user, content, 'like', now)19 Make changes to Article: like_count + 120 Schedule: update_user_interests for Current User2122Interest Profile Update (Backend Workflow):23 Search UserInteractions where user = target, type = like/save24 Collect categories from interacted content25 Find top 5 most frequent categories26 Update User's user_interests list2728Recommendation Query:29 Primary (returning users):30 Search Articles where31 categories contains list Current User's user_interests32 AND unique id NOT IN user's viewed content33 Sorted by: Created Date descending34 Limit: 1035 36 Fallback (new users):37 Search Articles sorted by like_count descending38 Limit: 103940Feedback Loop:41 'Not interested' → Create dismiss interaction, hide item42 'More like this' → Create like interaction, update interestsCommon mistakes when building content recommendations in Bubble
Why it's a problem: Using the :filtered operator on large content databases
How to avoid: Maintain a 'viewed_content' list on the User Data Type and use it as a database constraint. Or use a 'not in' exclusion approach with smaller result sets.
Why it's a problem: Treating all interactions equally
How to avoid: Only use likes and saves (not views) for building the interest profile. Use views only for the 'already seen' exclusion filter.
Why it's a problem: Not providing recommendations for new users
How to avoid: Always have a popularity-based fallback that shows trending or most-liked content when the user's interest profile is empty.
Best practices
- Track interactions at different weights: views for exclusion, likes and saves for interest profiling
- Update user interest profiles asynchronously via backend workflows to avoid slowing down the UI
- Always provide a fallback (popular/trending content) for new users with no interaction history
- Exclude already-viewed content from recommendations to keep suggestions fresh
- Add explicit feedback controls (not interested / show more) to improve recommendation quality
- Limit recommendation queries to 10-15 items per load with a 'Load more' button for performance
- Use Option Sets for categories instead of free text to ensure consistent matching
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
How do I build a content recommendation system in Bubble.io? I want to track user views and likes, build interest profiles, and show a 'Recommended for You' section that excludes already-seen content. Include a fallback for new users and feedback controls.
Build a content recommendation engine for my app. Track user interactions (views, likes, saves) on articles, build a user interest profile from liked categories, and create a recommendations section showing unviewed articles matching user interests. Add a popularity fallback for new users.
Frequently asked questions
Do I need machine learning for a recommendation system?
No. A category-matching system built with Bubble's native search capabilities works well for most apps. ML-based recommendations are only needed at scale (millions of users and content items).
How do I handle users who interact with many different categories?
Limit the interest profile to the top 5 most frequent categories. This prevents the recommendations from becoming too broad. Update the profile regularly to reflect changing interests.
Can I show recommendations in real time as users browse?
Yes. After each interaction, trigger an interest profile update and refresh the recommendation section. However, for performance, it is better to update interests periodically (e.g., after every 5 interactions).
How do I measure if my recommendations are working?
Track the click-through rate on recommended items versus non-recommended items. If users are clicking on recommendations at a higher rate, the system is working. Log these metrics in your engagement tracking system.
Can RapidDev help build an advanced recommendation engine?
Yes. RapidDev can implement sophisticated recommendation systems in Bubble, including collaborative filtering, content-based filtering, and hybrid approaches that combine multiple signals for better accuracy.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation