# How to Add Live Streaming to a Bubble App

- Tool: Bubble
- Difficulty: Beginner
- Time required: 25-30 min
- Compatibility: All Bubble plans (streaming service required)
- Last updated: March 2026

## TL;DR

Live streaming in Bubble requires integrating a third-party streaming service like Mux, Agora, or YouTube Live because Bubble has no native video streaming. You create streams via API, embed the player in an HTML element, add a live chat alongside the stream, and optionally record streams for replay. This tutorial covers the full integration from stream creation to viewer experience.

## Overview: Live Streaming in Bubble

This tutorial shows how to add live video streaming to your Bubble app by integrating a streaming service. You will create live streams via API, embed players, build a chat sidebar, and enable recording.

## Before you start

- A Bubble app with user authentication
- An account with a streaming service (Mux, Agora, or YouTube Live)
- API Connector plugin installed
- Understanding of HTML elements in Bubble

## Step-by-step guide

### 1. Choose and configure a streaming service

Mux is recommended for Bubble integration — it provides simple APIs for stream creation and an embeddable HLS player. Sign up at mux.com, create a project, and get your API access token and secret. Store these in the API Connector as private parameters. Alternative: use YouTube Live API for free streaming with existing YouTube infrastructure.

**Expected result:** A streaming service account is configured with API credentials stored securely in Bubble.

### 2. Create live streams via the API Connector

In the API Connector, set up a POST call to Mux's live stream creation endpoint (https://api.mux.com/video/v1/live-streams). Set authentication to HTTP Basic Auth with your Mux access token and secret. The request body specifies stream settings like playback policy and whether to record. Initialize the call. This returns a stream key (for the broadcaster) and a playback ID (for viewers).

```
{
  "playback_policy": ["public"],
  "new_asset_settings": {
    "playback_policy": ["public"]
  },
  "reduced_latency": true
}
```

**Expected result:** An API call creates live streams on demand and returns stream keys and playback IDs.

### 3. Build the broadcaster and viewer pages

Create a 'go-live' page for broadcasters. Display the stream key and RTMP URL (rtmp://global-live.mux.com/app) that the broadcaster enters into OBS, Streamyard, or similar streaming software. Create a 'watch' page for viewers with an HTML element containing the Mux Player embed. Use the playback ID from the stream record to construct the player URL. The Mux Player web component handles all playback controls.

```
<script src="https://cdn.jsdelivr.net/npm/@mux/mux-player"></script>
<mux-player
  stream-type="live"
  playback-id="PLAYBACK_ID_HERE"
  metadata-video-title="Live Stream"
  style="width:100%;aspect-ratio:16/9;"
></mux-player>
```

**Expected result:** Broadcasters can start streaming via OBS, and viewers see the live stream in an embedded player.

### 4. Add a live chat sidebar

Next to the video player, add a chat section using the chat system pattern: a Repeating Group of Messages filtered by stream ID, sorted by timestamp ascending, with a text input and Send button below. Use Bubble's live data for real-time message display. Add the sender's name and a timestamp to each message. Optionally add moderation controls for the stream host to delete messages.

**Expected result:** A real-time chat runs alongside the live stream, allowing viewers to interact during the broadcast.

### 5. Enable recording and replay

When creating the Mux stream, set 'new_asset_settings' to enable recording. After the stream ends, Mux automatically creates a video asset with its own playback ID. Store this asset ID in your Stream Data Type. On a 'replays' page, list completed streams with their recording available. Use the same Mux Player embed but with the asset's playback ID instead of the live stream's.

**Expected result:** Live streams are automatically recorded, and viewers can watch replays after the broadcast ends.

### 6. Track viewer count and stream status

Create a 'StreamSession' Data Type to track active viewers. When a user opens the watch page, create a StreamSession record. When they leave, delete it. Display the count of active sessions as the viewer count. For stream status, use Mux webhooks (video.live_stream.active and video.live_stream.idle) via a backend API endpoint to update the stream's status in your database.

**Expected result:** The stream page shows live viewer count, and stream status updates automatically when the broadcaster starts or stops.

## Complete code example

File: `Workflow summary`

```text
LIVE STREAMING — WORKFLOW SUMMARY
====================================

SERVICE: Mux (recommended) or YouTube Live
CREDENTIALS: API Connector (private, HTTP Basic Auth)

DATA TYPE: Stream
  title, host (User), stream_key, playback_id,
  status (live/ended/scheduled), recording_id,
  start_time, end_time, viewer_count

CREATE STREAM:
  API Connector POST → Mux live-streams
  Store stream_key + playback_id in Stream record

BROADCAST PAGE:
  Display: RTMP URL + stream key
  Broadcaster uses OBS/Streamyard

VIEWER PAGE:
  Mux Player embed with playback_id
  Live chat: Messages RG + input + send
  Viewer count: count active StreamSessions

RECORDING:
  Mux auto-creates asset after stream ends
  Webhook → store asset playback_id
  Replay page: Mux Player with asset ID

WEBHOOKS:
  live_stream.active → status = 'live'
  live_stream.idle → status = 'ended'
```

## Common mistakes

- **Exposing the stream key to viewers** — Anyone with the stream key can broadcast to your stream, potentially hijacking it Fix: Only show the stream key on the broadcaster's page behind authentication. Use Privacy Rules to restrict access.
- **Not implementing webhooks for stream status** — Without webhooks, your app does not know when a stream starts or ends, showing incorrect status to viewers Fix: Set up Mux webhook endpoints in Bubble backend workflows to update stream status automatically
- **Loading the chat without pagination for long streams** — A 2-hour stream can generate thousands of chat messages, causing the Repeating Group to slow dramatically Fix: Limit the chat display to the last 50-100 messages and auto-scroll to the latest

## Best practices

- Use Mux for the simplest Bubble integration with HLS player and recording
- Store stream credentials securely — never expose stream keys to viewers
- Implement webhooks for real-time stream status updates
- Limit chat message display to recent messages for performance
- Enable recording by default so broadcasts are available for replay
- Add moderation tools for the host to manage chat during live streams
- Track viewer count for analytics and to display social proof during broadcasts

## Frequently asked questions

### How much does Mux cost for live streaming?

Mux charges $0.005 per minute of live stream delivery per viewer. A 1-hour stream with 100 viewers costs about $30. They offer a free tier with limited minutes for testing.

### Can viewers stream from their browser without OBS?

Yes. Use Mux's browser-based broadcasting with their WebRTC SDK, or embed a simpler service like StreamYard. This removes the need for external software.

### Can I add screen sharing to the live stream?

Yes. OBS and StreamYard both support screen sharing as a source. For browser-based broadcasting, use the WebRTC getDisplayMedia API.

### How do I handle streams with hundreds of viewers?

Mux handles scaling automatically — their CDN distributes the stream globally. For chat, implement server-side message rate limiting and pagination.

### Can RapidDev build a complete streaming platform in Bubble?

Yes. RapidDev can build live streaming platforms with broadcast management, viewer experience, chat, recording, monetization, and analytics in Bubble.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/add-a-live-stream-feature-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/add-a-live-stream-feature-in-bubble
