# How to build a CMS in Bubble

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

## TL;DR

Build a full content management system in Bubble with content types, a WYSIWYG editor, image management, scheduling, and role-based editorial workflows. This tutorial covers creating an admin CMS interface for managing blog posts, pages, and media that renders on your public-facing site.

## Overview: Building a CMS in Bubble

A CMS lets your team create, edit, and publish content without touching the app's design. This tutorial builds an admin-focused content management system with a rich text editor, media library, draft/publish states, and editorial roles.

## Before you start

- A Bubble account with user authentication and roles
- The Rich Text Editor element or a plugin like Quill/TinyMCE
- Basic understanding of Data Types, Workflows, and privacy rules

## Step-by-step guide

### 1. Design the CMS data model

Create Data Types: 'Article' with title (text), slug (text), body (text — stores rich text HTML), excerpt (text), cover_image (image), category (Option Set), status (Option Set: Draft/InReview/Published), author (User), published_date (date), seo_title (text), seo_description (text). Create 'MediaItem': file (file), name (text), uploaded_by (User), tags (list of text).

**Expected result:** CMS data types with editorial workflow fields are ready.

### 2. Build the article editor page

Create an 'admin-editor' page (restricted to admin/editor roles). Add inputs for title, slug (auto-generated from title), excerpt, category dropdown, and cover image uploader. Add a Rich Text Editor element for the body content. Add a Save Draft button (creates/updates Article with status = Draft) and a Publish button (sets status = Published, published_date = Current date/time).

**Expected result:** Admins can create and edit articles with rich text formatting.

### 3. Create the article listing and management page

Build an 'admin-articles' page with a Repeating Group showing all Articles sorted by date. Each row displays title, author, status badge, and published date. Add filter tabs: All, Drafts, Published. Add Edit and Delete buttons per row. The Edit button navigates to admin-editor with the article's ID.

**Expected result:** Admins can browse, filter, edit, and delete all articles.

### 4. Implement the editorial workflow

Add a Submit for Review button that changes status to InReview and notifies editors. Editors see InReview articles in their queue and can Approve (status → Published) or Request Changes (status → Draft with a feedback note). Use privacy rules so writers can only edit their own drafts while editors can approve any article.

> Pro tip: Add an 'editor_notes' field for feedback when requesting changes on submitted articles.

**Expected result:** A multi-step editorial workflow with roles for writers and editors.

### 5. Render CMS content on public pages

Create a dynamic 'article' page that reads the slug from the URL. Data source: Do a search for Article where slug = Get slug from page URL and status = Published. Display the title in an H1, cover image, author name, published date, and body content in a Rich Text element (which renders HTML safely). Add meta tags using the SEO fields.

**Expected result:** Published articles display on public-facing pages with proper formatting and SEO metadata.

### 6. Build the media library

Create an 'admin-media' page with a file uploader that creates MediaItem records. Display all media in a grid Repeating Group with thumbnails. Add a search bar filtering by name or tags. When editing an article, add a 'Insert Image' button that opens the media library in a popup — clicking an image inserts its URL into the Rich Text Editor.

**Expected result:** A centralized media library for managing and inserting images across articles.

## Complete code example

File: `Workflow summary`

```text
CMS — ARCHITECTURE SUMMARY
============================

DATA TYPES:
  Article: title, slug, body (HTML), excerpt, cover_image,
           category, status (Draft/InReview/Published),
           author, published_date, seo_title, seo_description
  MediaItem: file, name, uploaded_by, tags

ROLES:
  Writer: create articles, edit own drafts, submit for review
  Editor: review submitted articles, approve/reject, publish
  Admin: full access to all content and settings

EDITORIAL WORKFLOW:
  Writer creates → Draft
  Writer submits → InReview
  Editor reviews → Published or → Draft (with notes)

PAGES:
  admin-articles — Article listing with filters
  admin-editor   — Rich text editor with save/publish
  admin-media    — Media library grid
  article (public) — Dynamic page rendering published content

SEO:
  Each article has seo_title and seo_description
  Dynamic meta tags set on the public article page
```

## Common mistakes

- **Not sanitizing rich text HTML before display** — Malicious HTML or scripts in article body could create XSS vulnerabilities Fix: Use Bubble's Rich Text element for display — it sanitizes HTML automatically
- **Generating slugs with special characters** — URLs with spaces or special characters break navigation and SEO Fix: Auto-generate slugs by converting title to lowercase, replacing spaces with hyphens, and removing special characters
- **Not restricting the admin pages to authorized roles** — Any user could access the CMS editor and modify content Fix: Add Page is loaded redirects: When Current User's role is not admin/editor → Go to index

## Best practices

- Auto-generate URL slugs from article titles
- Use an editorial workflow with draft/review/publish states
- Restrict admin pages with role-based redirects
- Add SEO fields for custom meta titles and descriptions
- Build a media library for centralized image management
- Display rich text content using Bubble's Rich Text element for safe HTML rendering
- Schedule articles for future publication using a backend workflow

## Frequently asked questions

### Can I schedule articles for future publication?

Yes. Add a scheduled_date field. Use a recurring backend workflow that checks for articles with scheduled_date <= now and status = Draft, then changes them to Published.

### How do I add categories to the CMS?

Create a Category Option Set or Data Type. Add a category field on Article. Display categories as filter tabs on listing pages and as navigation on the public site.

### Can multiple writers collaborate on one article?

Not simultaneously in the editor. Use a check-out system: when a writer opens an article for editing, set an 'editing_by' field to block others until they save.

### How do I add comments to articles?

Create a Comment data type linked to Article. Display comments on the public article page and add moderation tools in the admin.

### Can I version articles?

Create an ArticleVersion data type that stores snapshots of body, title, and date. Save a version each time the article is published.

### Can RapidDev build a custom CMS?

Yes. RapidDev builds content management systems with advanced features like version history, multi-language support, and custom content workflows.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/build-a-content-management-system-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/build-a-content-management-system-in-bubble
