Building a blog in Bubble involves creating a Post Data Type with fields for title, body, author, and category, a rich text editor for writing, a dynamic blog post page, and an index page with a Repeating Group showing all posts. This tutorial covers the full system including SEO-friendly URLs, categories, and a basic CMS dashboard.
Overview: Setting Up a Blog in Bubble
A blog is one of the most common features in web apps, and Bubble gives you everything you need to build one from scratch. Unlike WordPress where the blog structure is predefined, in Bubble you design every piece — the data structure, editor, listing page, and individual post pages. This gives you complete control over the design and functionality.
Prerequisites
- A Bubble app where you want to add a blog
- Basic familiarity with Bubble Data Types and the Design tab
- Understanding of dynamic pages and page data types
- A rich text editor plugin installed (e.g., Rich Text Editor by ZeroqodeX)
Step-by-step guide
Create the Post Data Type and related types
Create the Post Data Type and related types
Go to the Data tab and create a new Data Type called Post. Add these fields: title (text), body (text — this will hold the rich text HTML), excerpt (text — a short summary for the listing page), featured_image (image), author (User), category (text or an Option Set), tags (text, list), published (yes/no, default: no), published_date (date), and slug (text — for SEO-friendly URLs). Optionally create a Category Option Set with entries like Technology, Business, Tutorial.
Pro tip: Use an Option Set for categories instead of a text field — it is faster to query, consistent, and does not cost Workload Units for lookups.
Expected result: A Post Data Type with all necessary fields and optionally a Category Option Set.
Build the blog post editor page
Build the blog post editor page
Create a new page called blog-admin or post-editor. Add an Input element for the post title, a Rich Text Editor element (from the plugin you installed) for the body content, an Input for the excerpt, a File Uploader for the featured image, a Dropdown for the category (source: All Categories Option Set), and a multi-tag input or Repeating Group for tags. Add a Save as Draft button and a Publish button.
Expected result: An admin page with a full editor interface for creating and editing blog posts.
Set up the save and publish workflows
Set up the save and publish workflows
For the Save as Draft button workflow: Create a new Post with all field values, setting published to no. For the Publish button workflow: Create a new Post (or Make Changes if editing) with published set to yes and published_date set to Current date/time. Also set the slug using the Set a Thing's Slug action — use the title formatted as a URL-safe string. Add a condition to check that the title is not empty before allowing save.
Pro tip: Use Set a Thing's Slug (not Make Changes) to set the slug — this is a separate action specific to the slug field.
Expected result: Authors can save posts as drafts or publish them immediately, with SEO-friendly slugs auto-generated.
Create the dynamic blog post page
Create the dynamic blog post page
Create a new page called blog-post. Set its Type of content to Post (in the page settings). This makes the page expect a Post record as its data source. Add elements to display the post: a Text element for the title (dynamic data: Current Page Post's title), an Image for the featured image, a Text element for the published date, a Text for the author name, and an HTML element for the body content (because the rich text editor outputs HTML). Set the HTML source to Current Page Post's body.
Expected result: A dynamic page that displays any blog post passed to it, with proper title, image, date, and body rendering.
Build the blog index page with a Repeating Group
Build the blog index page with a Repeating Group
Create a page called blog. Add a Repeating Group with Type of content set to Post and Data source set to Do a Search for Posts where published = yes, sorted by published_date descending. Inside each cell, add: the featured image, post title (as a clickable link), the excerpt, the category, and the published date. Make the title or a Read More link navigate to the blog-post page, sending the current cell's Post as the data.
Pro tip: Add a Category filter dropdown above the Repeating Group and add category = Dropdown's value as a constraint with Ignore empty constraints checked.
Expected result: A blog listing page showing all published posts with images, titles, excerpts, and links to the full post.
Add SEO meta tags to the blog post page
Add SEO meta tags to the blog post page
On the blog-post page, go to the page settings and configure the SEO meta tags dynamically. Set the Page title to Current Page Post's title. Set the meta description to Current Page Post's excerpt. Set the OG image to Current Page Post's featured_image. These dynamic meta tags ensure each blog post has unique SEO metadata when shared on social media or indexed by search engines.
Expected result: Each blog post has unique meta tags for SEO and social sharing.
Complete working example
1BLOG SYSTEM SUMMARY2====================34DATA STRUCTURE:5 Post Data Type:6 - title (text)7 - body (text — rich text HTML)8 - excerpt (text — 150-200 chars)9 - featured_image (image)10 - author (User)11 - category (Category Option Set)12 - tags (text, list)13 - published (yes/no, default: no)14 - published_date (date)15 - slug (text — auto-set)1617 Category Option Set:18 - Technology19 - Business20 - Tutorial21 - News2223PAGES:24 1. blog-admin (post editor, admin only)25 2. blog (index/listing page)26 3. blog-post (dynamic individual post page, type: Post)2728EDITOR WORKFLOWS:29 Save Draft button:30 Action: Create a new Post31 → title, body, excerpt, featured_image, author = Current User32 → published = no33 Action: Set a Thing's Slug on Result of Step 134 → Slug: title (auto-formatted)3536 Publish button:37 Action: Create a new Post (or Make Changes)38 → published = yes39 → published_date = Current date/time40 Action: Set a Thing's Slug4142INDEX PAGE:43 RepeatingGroup:44 Type: Post45 Source: Search for Posts46 → published = yes47 → Sort: published_date descending48 Cell: image, title (link to blog-post), excerpt, category, date4950DYNAMIC POST PAGE:51 Page type: Post52 Elements:53 - Text: Current Page Post's title (H1 style)54 - Image: Current Page Post's featured_image55 - Text: Current Page Post's published_date formatted as MMM D, YYYY56 - Text: Current Page Post's author's name57 - HTML: Current Page Post's body5859SEO (blog-post page settings):60 Page title: Current Page Post's title61 Meta description: Current Page Post's excerpt62 OG image: Current Page Post's featured_imageCommon mistakes when building a blog in Bubble
Why it's a problem: Using a Text element to display rich text body content
How to avoid: Use an HTML element to display the body content — it renders the HTML markup correctly
Why it's a problem: Not setting the page type on the blog-post page
How to avoid: In the blog-post page settings, set Type of content to Post before adding any dynamic elements
Why it's a problem: Forgetting to filter by published = yes on the index page
How to avoid: Add published = yes as a constraint on the Repeating Group's Do a Search for expression
Best practices
- Use an Option Set for categories for better performance and consistency
- Set SEO meta tags dynamically on the blog post page using Current Page Post data
- Generate URL slugs from the post title using Set a Thing's Slug for SEO-friendly URLs
- Add an excerpt field for listing pages instead of truncating the full body text
- Restrict the blog editor page to admin users with Privacy Rules or page-level conditions
- Add pagination to the blog index Repeating Group (10-15 posts per page)
- Include a featured image on every post for better visual impact on the listing page and social shares
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I want to build a full blog system in my Bubble.io app with a post editor, dynamic post pages, an index with categories, and SEO meta tags. Can you walk me through the Data Types, pages, and workflows I need?
Build a blog system for my app. I need a Post Data Type, a rich text editor page for writing, a dynamic blog post page, and a blog index with categories. Set up SEO-friendly slugs and meta tags.
Frequently asked questions
Which rich text editor plugin should I use?
Popular options include the Rich Text Editor by ZeroqodeX, the TinyMCE plugin, and Quill-based editors. Choose one that supports image embedding, formatting, and outputs clean HTML.
Can I schedule posts to publish in the future?
Yes. Add a scheduled_publish_date field to your Post. Create a backend workflow that checks for unpublished posts where scheduled_publish_date has passed, and sets published to yes. Schedule it to run every hour.
How do I add comments to blog posts?
Create a Comment Data Type with fields for body (text), author (User), and post (Post). Add a comment form and Repeating Group on the blog-post page. Privacy Rules control who can comment.
Will my blog posts be indexed by Google?
Yes, if you set up meta tags and a sitemap. Bubble renders content server-side for search engine crawlers, so your dynamic post pages are indexable.
Can I let multiple authors write posts?
Yes. The author field on Post links to the User who created it. Add a role field to your User type and restrict the editor page to users with an author or admin role.
How do I handle blog SEO beyond meta tags?
Add structured data, canonical URLs, and ensure fast page loads. For comprehensive blog SEO strategy in Bubble, RapidDev can help optimize your blog for search engine rankings and Core Web Vitals.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation