# How to Build a Social Networking Site in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 45-60 min
- Compatibility: All Bubble plans (Growth plan+ recommended for active networks)
- Last updated: March 2026

## TL;DR

Build a fully functional social networking site in Bubble with user profiles, a friend and follow system, a personalized news feed, image posts, likes, comments, and per-post privacy controls. This tutorial walks through the complete data model, profile pages with edit capability, a follow system with mutual-connection detection, a filtered news feed, and social interactions -- all without writing a single line of code.

## Overview: Building a Social Networking Site in Bubble

Social networking apps are among the most popular projects built in Bubble, and the platform gives you every visual building block you need. This tutorial covers user profiles with avatars and bios, a follow system that tracks connections, a real-time news feed filtered to followed users, posting with optional images, a like toggle, threaded comments, and per-post privacy controls. It is designed for non-technical founders who want to launch a working social platform and test it with real users.

## Before you start

- A Bubble account with user sign-up and login already configured
- Basic familiarity with Data Types, Repeating Groups, and Workflows
- Understanding of Privacy Rules for restricting data access
- A plan for your social network niche (alumni, hobbyists, professionals, etc.)

## Step-by-step guide

### 1. Create the social-network data model

Open the Data tab and create the following Data Types. First, extend the built-in User type by adding these fields: display_name (text), bio (text), avatar (image), cover_photo (image), followers_count (number, default 0), following_count (number, default 0). Next, create a 'Follow' Data Type with two fields: follower (User) and following (User). Create a 'Post' Data Type: author (User), content (text), image (image), visibility (text, default 'public'), likes_count (number, default 0), comments_count (number, default 0). Create a 'Like' Data Type: post (Post), user (User). Finally, create a 'Comment' Data Type: post (Post), author (User), content (text). Using a separate Follow Data Type instead of a list on User keeps the database fast even as your network grows.

> Pro tip: Create an Option Set called PostVisibility with three options: Public, Friends Only, Only Me. Reference it in dropdowns and conditionals to avoid typos from plain text values.

**Expected result:** Five Data Types and one Option Set appear in the Data tab, covering the full social networking data model.

### 2. Build user profile pages with edit functionality

Create a new page called 'profile' and set its Type of content to User. At the top, add a Group element with the cover_photo displayed as a background image. Inside it, place a circular Image element showing the avatar, a Text element for display_name, and a smaller Text element for bio. Below, display two counts: 'X followers' (Do a search for Follow where following = This page's User :count) and 'X following' (Do a search for Follow where follower = This page's User :count). Add an 'Edit Profile' button with a conditional: This button is visible only when Current User is This page's User. When clicked, show a Popup element containing Input fields for display_name, bio, a File Uploader for avatar, and a File Uploader for cover_photo. The Save button workflow: Make changes to Current User -- set display_name, bio, avatar, and cover_photo to the corresponding input values -- then hide the popup and reset the inputs.

**Expected result:** A profile page displays any user's information, follower and following counts, and lets the logged-in user edit their own profile through a popup form.

### 3. Implement the follow and unfollow system

On the profile page, add a Follow button visible only when This page's User is not Current User. Add two conditionals on the button. Conditional 1: When Do a search for Follow (follower = Current User, following = This page's User) :count is 0, set the button text to 'Follow' with a filled style. Conditional 2: When the same search count is greater than 0, set the button text to 'Unfollow' with an outline style. Create two workflows on this button. Workflow 1 (Follow): Only when the search count is 0, create a new Follow record (follower = Current User, following = This page's User), then Make changes to This page's User (followers_count + 1) and Make changes to Current User (following_count + 1). Workflow 2 (Unfollow): Only when the search count is greater than 0, search for the Follow record and delete it via :first item, then decrement both users' counts by 1.

**Expected result:** Clicking Follow creates a Follow record and increments counts; clicking Unfollow removes it and decrements counts. The button text toggles automatically.

### 4. Create the personalized news feed

Create a new page called 'feed'. At the top, add a posting form: a Multiline Input for text content, a File Uploader for an optional image, a Dropdown sourced from the PostVisibility Option Set, and a 'Post' button. The Post button workflow: Create a new Post -- author = Current User, content = Multiline Input's value, image = File Uploader's value, visibility = Dropdown's value -- then reset the form inputs. Below the form, add a Repeating Group with type Post. Set the data source to: Do a search for Post where author is in (Do a search for Follow where follower = Current User :each item's following), sorted by Created Date descending. In each cell, display the author's avatar (linked to their profile page), display_name, the post content, the image (only visible when image is not empty), a timestamp formatted as a relative date, likes_count, and comments_count. Set the Repeating Group to show 15 items per page.

> Pro tip: Add a tab row above the feed with Following and Discover options. The Discover tab removes the author filter and shows all public posts, helping users find new accounts to follow.

**Expected result:** The feed shows posts only from users the current user follows, in reverse chronological order, with a form at the top for creating new posts.

### 5. Add like toggling and threaded comments

In each Repeating Group cell, add a heart Icon element as the like button. Set a conditional: when Do a search for Like (post = Current cell's Post, user = Current User) :count is greater than 0, change the icon color to red and set the icon to a filled heart. Create a workflow on the icon: Step 1 (Only when not liked): Create a new Like (post = Current cell's Post, user = Current User) and Make changes to Current cell's Post (likes_count + 1). Step 2 (Only when already liked): Delete the Like record via search :first item and decrement likes_count by 1. Below the post content, add a 'View X comments' link that toggles a collapsible Group. Inside the group, place a nested Repeating Group searching for Comments where post = Current cell's Post, sorted by Created Date ascending. At the bottom of this group, add an Input and a Reply button. The Reply workflow: Create a new Comment (post = Current cell's Post, author = Current User, content = Input's value), increment the Post's comments_count by 1, then reset the input.

**Expected result:** Users can toggle likes with a heart icon that turns red when liked, and view or add comments in a threaded section beneath each post.

### 6. Configure privacy rules for post visibility

Go to the Data tab and click the Privacy tab. Select the Post Data Type. Create three privacy rules. Rule 1 -- Public posts: When This Post's visibility is 'Public', all fields are viewable by everyone. Rule 2 -- Friends Only: When This Post's visibility is 'Friends Only', all fields are viewable only when Do a search for Follow (follower = Current User, following = This Post's author) :count is greater than 0, or Current User is This Post's author. Rule 3 -- Only Me: When This Post's visibility is 'Only Me', all fields are viewable only when Current User is This Post's author. For the Like Data Type, allow everyone to view all fields. For the Comment Data Type, allow everyone to view all fields (the parent Post's privacy rule already prevents hidden posts from appearing). These server-side rules automatically filter search results so private posts never appear in feeds or searches for unauthorized users.

> Pro tip: Test privacy rules by opening two browser windows logged in as different test users. Create a Friends Only post from one account and verify it only shows up in the other account's feed after that account follows the author.

**Expected result:** Posts respect the author's chosen visibility -- public posts are visible to all, friends-only posts appear only for followers, and only-me posts are visible exclusively to the author.

## Complete code example

File: `Workflow summary`

```text
SOCIAL NETWORKING SITE — FULL ARCHITECTURE
=============================================

DATA TYPES:
  User (extended):
    display_name (text), bio (text), avatar (image),
    cover_photo (image), followers_count (number),
    following_count (number)
  Follow:
    follower (User), following (User)
  Post:
    author (User), content (text), image (image),
    visibility (Option Set: PostVisibility),
    likes_count (number), comments_count (number)
  Like:
    post (Post), user (User)
  Comment:
    post (Post), author (User), content (text)

OPTION SETS:
  PostVisibility: Public | Friends Only | Only Me

PAGES:
  feed     — Post creation form + personalized news feed
  profile  — User info, follower/following counts, edit popup

KEY WORKFLOWS:
  Create Post:
    Button → Create Post (author, content, image, visibility)
    → Reset form inputs
  Follow User:
    Button (when not following) → Create Follow record
    → Increment both users' counts
  Unfollow User:
    Button (when following) → Delete Follow record
    → Decrement both users' counts
  Like Post:
    Heart icon (when not liked) → Create Like
    → Increment likes_count
  Unlike Post:
    Heart icon (when liked) → Delete Like
    → Decrement likes_count
  Add Comment:
    Reply button → Create Comment
    → Increment comments_count → Reset input
  Edit Profile:
    Save button → Make changes to User fields
    → Hide popup

FEED DATA SOURCE:
  Do a search for Post
    where author is in
      (Search Follow where follower = Current User)
        :each item's following
    Sorted by Created Date descending
    Items per page: 15

PRIVACY RULES:
  Post (Public):       Everyone can view
  Post (Friends Only): Viewer must follow author, or be author
  Post (Only Me):      Only author can view
  Like:                Everyone can view
  Comment:             Everyone can view
  Follow:              Everyone can view
```

## Common mistakes

- **Storing followers as a list field on the User record instead of a separate Follow Data Type** — List fields slow down significantly past a few thousand entries and cannot be efficiently searched, sorted, or paginated Fix: Use a separate Follow Data Type with follower and following fields so each connection is its own record that Bubble can index
- **Not preventing duplicate likes from the same user on the same post** — Without a check, a user can click the heart icon multiple times and inflate the likes_count beyond the actual number of unique likers Fix: Before creating a Like, search for an existing Like with the same post and user -- only create if the count is 0
- **Forgetting to set Privacy Rules on the Post Data Type** — Without server-side privacy rules, all posts including Friends Only and Only Me posts appear in every user's search results and feeds Fix: Configure privacy rules in Data → Privacy so that visibility-restricted posts are filtered at the database level before data reaches the client
- **Loading the entire post history in the feed without pagination** — An active social network generates hundreds of posts quickly and loading them all at once causes slow rendering and high memory usage Fix: Set the Repeating Group to show 10-20 items per page and add infinite scroll or a Load More button for additional content

## Best practices

- Denormalize likes_count, comments_count, followers_count, and following_count directly on their parent records to avoid expensive count searches on every page load
- Use a separate Follow Data Type instead of list fields on User so connections can be searched and paginated efficiently
- Paginate the news feed to 10-20 posts per page and implement infinite scroll for a smooth experience
- Create reusable elements for post cards and profile headers so the same layout works across feed, profile, and search pages
- Use Option Sets for post visibility values to avoid typos and simplify conditionals
- Test privacy rules with multiple browser sessions logged in as different users before launching to real users
- Add a Discover tab to the feed page showing all public posts so users can find new accounts to follow

## Frequently asked questions

### How many users can a Bubble social network support?

With optimized searches, pagination, and denormalized counts, Bubble social networks handle communities of tens of thousands of active users. For networks expecting hundreds of thousands, consider offloading heavy feed queries to an external service via API.

### Does the news feed update in real time when someone posts?

Yes. Repeating Groups bound to database searches auto-refresh via WebSocket when new records are created. A new post from a followed user appears in your feed without a page reload.

### How do I add notifications for likes, comments, and new followers?

Create a Notification Data Type with fields for recipient, type (like, comment, follow), related_post, sender, and is_read. Add a Create Notification step to each relevant workflow and display unread notifications in a bell-icon dropdown.

### Can I detect mutual follows (friends)?

Yes. A mutual follow exists when there is a Follow record in both directions. Search for Follow where follower = User A and following = User B, then check if a reverse record also exists. Display a Friends badge on the profile when both records are found.

### How do I prevent spam accounts from flooding the feed?

Add rate limiting by checking if the user posted within the last 60 seconds before allowing a new post. You can also require email verification before granting posting privileges and add a report button for flagging abusive content.

### Can RapidDev help build a production-ready social network?

Yes. RapidDev builds social networking platforms in Bubble with advanced features like recommendation algorithms, content moderation pipelines, push notifications, and performance optimization for high-traffic networks.

### Can I add image galleries or multi-image posts?

Yes. Change the Post image field to a list of images and use a Multi-file Uploader in the posting form. Display images in a horizontal scrolling Repeating Group or a lightbox grid inside each post card.

### How do I add stories that disappear after 24 hours?

Create a Story Data Type with author, media (image or video), and expiry_date (set to Created Date plus 24 hours). Display active stories in a horizontal Repeating Group at the top of the feed, filtering by expiry_date is after Current date/time.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/build-a-social-networking-site-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/build-a-social-networking-site-in-bubble
