A full RSS feed reader app in Bubble lets users add multiple feed sources, fetches articles via an RSS-to-JSON API, stores them in the database, and provides category-based browsing with read/unread tracking. This tutorial covers the complete build from feed source management to scheduled background refreshes and a clean reading interface.
Overview: Building an RSS Feed Reader App in Bubble
This tutorial walks through building a multi-source RSS feed reader similar to Feedly or Inoreader. Users can add their favorite RSS feeds, browse articles organized by category, mark items as read or saved, and enjoy automatic background refreshes. Unlike a simple RSS integration, this is a full reader application with user-specific preferences and reading history.
Prerequisites
- A Bubble account with an app
- The API Connector plugin installed
- Basic understanding of backend workflows for scheduling
- Familiarity with Repeating Groups and Data Types
Step-by-step guide
Create the data model for the feed reader
Create the data model for the feed reader
Go to the Data tab and create these Data Types. FeedSource: name (text), url (text), category (text), icon_url (text), owner (User), is_active (yes/no default yes), last_fetched (date). Article: title (text), link (text), description (text), thumbnail (text), pub_date (date), feed_source (FeedSource), content_hash (text). UserArticle: user (User), article (Article), is_read (yes/no default no), is_saved (yes/no default no), read_date (date). The UserArticle type tracks per-user reading state without modifying the shared Article records.
Pro tip: Use content_hash (a hash of the article link) to quickly check for duplicates during feed refresh. This is faster than searching by the full link text.
Expected result: Three Data Types are created to support multi-user feed reading with individual reading states.
Build the feed source management page
Build the feed source management page
Create a page called manage-feeds. Add an Input for the feed URL, an Input for the feed name, a Dropdown for category (News, Tech, Business, etc.), and an Add Feed button. Create a workflow: When Add Feed is clicked → Create a new FeedSource with the form values and owner = Current User. Below the form, add a Repeating Group showing Do a search for FeedSources where owner = Current User. Each cell displays the feed name, URL, category, and a Delete button. Add edit capability by clicking a cell to populate the form with the existing values.
Expected result: Users can add, view, and delete their RSS feed sources from a management page.
Set up the API Connector to fetch feeds
Set up the API Connector to fetch feeds
In the Plugins tab, open the API Connector. Create an API called RSS Parser with a call named Fetch Feed. Set the method to GET and the URL to https://api.rss2json.com/v1/api.json?rss_url=[feed_url]&count=20. Mark feed_url as not Private (so it can be set dynamically). Initialize with a real RSS feed URL. Set Use as to Action so it can be used in backend workflows. After initialization, verify that Bubble recognizes the items array with title, link, description, pubDate, and thumbnail fields.
Expected result: The API call is configured and can fetch any RSS feed by passing the URL as a parameter.
Build the article reading interface
Build the article reading interface
Create a page called reader. Add a sidebar Group with a list of the user's feed categories and a All Articles option. In the main area, add a Repeating Group for articles. Set the Data source to Do a search for Articles where feed_source's owner = Current User, sorted by pub_date descending. Add constraints based on the selected category. Inside each cell, display the article title, feed source name, pub_date, description snippet (first 150 characters), and thumbnail. Style unread articles with bold titles using a Conditional: When Do a search for UserArticles where article = This Article AND user = Current User AND is_read = no is not empty → font weight bold.
Expected result: A reader interface displays articles from all subscribed feeds with visual distinction between read and unread items.
Implement read tracking and saved articles
Implement read tracking and saved articles
When a user clicks an article title or an Open button, create a workflow: first check if a UserArticle record exists for this user and article. If not, Create a new UserArticle with user = Current User, article = Current cell's Article, is_read = yes, read_date = Current date/time. If it exists, Make changes to it: is_read = yes. Then open the article link in a new tab using Open an external website. Add a Save/Bookmark icon button that toggles is_saved on the UserArticle. Create a Saved Articles page that shows articles where UserArticle's is_saved = yes for the current user.
Expected result: Clicking an article marks it as read, and users can save articles for later reading.
Schedule automatic feed refreshes
Schedule automatic feed refreshes
Create a backend workflow called refresh-all-feeds. Step 1: Search for all active FeedSources (is_active = yes). Step 2: Use Schedule API Workflow on a List to call a second backend workflow refresh-single-feed for each source. In refresh-single-feed: call the RSS Parser Fetch Feed API with the source's URL. For each returned item, check if an Article with the same link already exists. If not, Create a new Article. Update the FeedSource's last_fetched date. Schedule refresh-all-feeds to run recursively every hour. Enable backend workflows in Settings → API tab.
Pro tip: For a growing user base with many feeds, consider batching refreshes to avoid hitting API rate limits. RapidDev can help optimize backend processing for high-volume feed aggregation.
Expected result: Feeds are automatically refreshed every hour in the background without any user action.
Complete working example
1RSS FEED READER APP WORKFLOW SUMMARY2=====================================34DATA TYPES:5 FeedSource6 - name (text), url (text), category (text)7 - icon_url (text), owner (User)8 - is_active (yes/no), last_fetched (date)910 Article11 - title (text), link (text), description (text)12 - thumbnail (text), pub_date (date)13 - feed_source (FeedSource)1415 UserArticle16 - user (User), article (Article)17 - is_read (yes/no), is_saved (yes/no)18 - read_date (date)1920API CONNECTOR:21 API: RSS Parser22 Call: Fetch Feed (GET, Action)23 URL: https://api.rss2json.com/v1/api.json?rss_url=[feed_url]&count=202425PAGES:26 manage-feeds: Add/edit/delete feed sources27 reader: Main reading interface with sidebar categories28 saved: Saved/bookmarked articles2930FRONTEND WORKFLOWS:31 1. Add Feed Source → Create FeedSource32 2. Open Article → Create/update UserArticle (is_read=yes)33 → Open external website (article link)34 3. Toggle Save → Make changes to UserArticle (is_saved)35 4. Mark All Read → Schedule API on list of UserArticles3637BACKEND WORKFLOWS:38 refresh-all-feeds (scheduled hourly):39 1. Search FeedSources where is_active = yes40 2. Schedule refresh-single-feed for each4142 refresh-single-feed:43 1. Call RSS Parser with source URL44 2. For each item: check if link exists45 3. If new: Create Article46 4. Update FeedSource last_fetched4748PRIVACY RULES:49 FeedSource: owner = Current User50 Article: feed_source's owner = Current User51 UserArticle: user = Current UserCommon mistakes when building an RSS feed reader in Bubble.io: Step-by-Step Guide
Why it's a problem: Storing read/unread state directly on the Article record
How to avoid: Use a separate UserArticle join table that tracks per-user reading state for each article.
Why it's a problem: Fetching feeds on page load instead of from the database
How to avoid: Store articles in the database and fetch from there. Use scheduled backend workflows to refresh feeds in the background.
Why it's a problem: Not deduplicating articles during refresh
How to avoid: Before creating an Article, check if one with the same link already exists. Only create new records for genuinely new articles.
Best practices
- Use a UserArticle join table for per-user reading state to support multi-user reading
- Store articles in the database and refresh via backend workflows for better performance
- Deduplicate articles by checking the link field before creating new records
- Paginate the article Repeating Group to 15-20 items for smooth scrolling
- Show visual indicators for unread articles (bold title, colored dot) using conditionals
- Group feeds by category in the sidebar for organized browsing
- Set up a Mark All as Read button for catching up quickly
- Add a search bar that filters articles by title for finding specific content
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a Feedly-like RSS reader in Bubble.io. I need users to manage their feed subscriptions, browse articles by category, track read/unread status per user, save articles, and auto-refresh feeds hourly. Can you design the data model and key workflows?
Build an RSS feed reader app. I need pages for managing feed sources, reading articles with category sidebar, read/unread tracking per user, saved articles, and scheduled backend workflows to refresh feeds automatically.
Frequently asked questions
How many feed sources can one user subscribe to?
There is no hard limit in Bubble, but performance degrades with many feeds being refreshed. For most users, 20-50 feeds work well. Beyond that, consider staggering refresh schedules.
Can I display the full article content instead of just the summary?
RSS feeds typically include only a summary. To get full content, you would need to scrape the article page, which requires an external service. Most RSS readers link to the original article instead.
How do I handle feeds that become unavailable?
In your refresh-single-feed workflow, check if the API call returns an error. If it fails, increment an error_count field on the FeedSource. After 3-5 consecutive failures, set is_active to no and notify the user.
Will this consume a lot of workload units?
Each feed refresh involves API calls and database writes. With 100 users each having 10 feeds refreshed hourly, that is 1,000 API calls plus article creation. Monitor your WU usage and adjust refresh frequency accordingly.
Can I add OPML import for migrating from another reader?
OPML is an XML format. You would need to parse it using an external service or a JavaScript plugin, then create FeedSource records for each feed URL found in the file.
Can RapidDev help build a production-grade feed reader?
Yes. RapidDev can help optimize feed processing, implement full-text search, add AI-powered article categorization, and build features like shared feeds and team collaboration.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation