Adding PubNub In-App Chat to your WebRTC Live Stream App


Adding a chatroom to your WebRTC live stream allows users and creators to communicate in real time improving engagement and community.

Chat functionality in some form has become ubiquitous with polished live stream experiences, allowing viewers to interact with each other and the content creator in real-time. Unfortunately for many stream participants, delays in the stream break the immersion of real-time interaction, limiting the relationship between the content creator and the viewer to intervals of 15 seconds or more. This is where Real-Time Streaming offers a natural synergy with real-time technology providers such as PubNub, allowing app builders to quickly build and deploy interactive audience engagement features (e.g. on/offline detection, live lobby counts, audience reactions, full-featured chat, CTA overlays, live polls, etc.) that improve engagement, drive a sense of community, increase time spent in-app, and even provide incremental inventory for monetization.

In this guide, we’ll be showing how you can add PubNub In-App Chat to a Real-Time Stream with just a few lines of JavaScript.

Image of author smiling on screen via a live stream, with a chat window built into the right of the live stream highlighting an arbitrary conversation between stream participants.
A WebRTC real-time stream with PubNub In-App Chat included.

How to Build with PubNub In-App Chat and Streaming

To get started building with PubNub and you first must have an active account with both platforms. Both PubNub and offer a “Free” tier for signing up allowing you to get started building, without having to input a credit card.

For this project, we’ll be building off of an earlier project Building a Low Latency Livestream Viewer where we demonstrated how to use the Streaming JavaScript SDK to build out a WebRTC live stream viewer app.

Note: All code for this project is available here on GitHub. Feel free to clone the repository and follow along.

Adding a Chatroom to a Live Stream App

The easiest way to get started adding a chat feature to your live stream app is to import the PubNub JavaScript SDK into your HTML file alongside any other SDKs you might be using such as the Streaming JavaScript SDK (formerly Millicast). If you are building on top of the Low Latency Livestream Viewer project you can add the PubNub JavaScript SDK to the head of the index.html file.

    <script src=""></script>
    <script src=""></script>

By leveraging the SDK we can simplify common chat-related actions such as adding messages to the chat room and syncing with messages sent by other users.  In addition to importing the SDKs, we also need to lay out the structure of our chatroom inside our HTML file. This is done in the body and should include a section for rendering sent messages, a section for inputting messages, and a submit button for sending the message.

    <div id="chatBox" class="chatBox" hidden="True">
        <div id="outputDiv" class="outputBox"></div>
        <input id="inputChat" class="messageBox" placeholder="" />
        <button class="enterButton" id="enterButton">Submit</button>

With the SDK imported and our chat widget structured, we are done with the HTML file, and can now switch over to our JavaScript file to handle the functionality of the chat feature.

Authenticating and Connecting to the PubNub API

In order to add in-app chat to your live stream app we need to authenticate and connect to the PubNub servers. To connect to the servers let’s first grab our Publish_Key and our Subscribe_Key from the PubNub dashboard.

Image of the Author's PubNub dashboard which includes Publish and Subscribe keys obfuscated from the user.
The PubNub dashboard. Note the “Recently created keys” heading that contains the PubNub authentication credentials.

Next, we want to define these publish keys within our JavaScript file so we can authenticate and connect to the server.

const PUBNUB_PUBLISH_KEY = "your_publish_key";
const PUBNUB_SUBSCRIBE_KEY = "your_subscribe_key";

Note: API keys should NOT be exposed to the public. If you are interested in a best practices guide for API key management click here.

With our keys defined we next need to define a username to connect with. This username will be what other participants see when interacting in the chat room and hence should be user-defined and human-readable. In our example app, we capture the username as the user connects logs into the live stream app via the usrName input tag. With these three parameters, we can call the PubNub SDK and create an authentication object.

let usrName = document.getElementById("usrName").value;
var pubnub = new PubNub({
            publishKey: PUBNUB_PUBLISH_KEY,
            subscribeKey: PUBNUB_SUBSCRIBE_KEY,
            userId: usrName,

Now that we have a valid authentication object we can subscribe to the chat stream. PubNub organizes chatrooms by channel where depending on the scope of your streaming app you might like to have multiple separate chatrooms. In this case, we will only use one chatroom, dlb_stream.

pubnub.subscribe({ channels: ["dlb_stream"] });

Finally, we can add an event listener using the pubnub object, that listens for new messages and updates the UI accordingly. The UI is updated with a function called newChat, which takes in the message and the publisher ID to update the UI with the new message.

chatBox = document.getElementById("outputDiv"),
    message: function (m) {
        chatBox.innerHTML += newChat(m.message, m.publisher);

Before we explore the functionality of newChat and how messages are organized and rendered in the UI, let’s add two more event listeners required for building a functional chat room.

Sending Messages with the PubNub API

In order to send messages we must have a way of “listening” to when the user is ready to send a message. One way to do this is to wait for the enter button to be pressed inside the inputText field. This can be done with keypress listener, which triggers when the enter key has been pressed. Once the listener triggers it calls the pubnub.publish function and delivers the message to the other users.

var inputText = document.getElementById("inputChat");
inputText.addEventListener("keypress", function (e) {
            (e.keyCode || e.charCode) === 13 &&
                inputText.value != "" &&
                    channel: channel,
                    message: inputText.value,
                    x: (inputText.value = ""),

Since all users are different we want our chatroom to cater to the individuals that prefer to click a button instead. In addition to listening for the enter button, we can also add a listener that waits for the Submit button to be clicked.

inputButton.addEventListener("click", function (e) {
            inputText.value != "" &&
                    channel: channel,
                    message: inputText.value,
                    x: (inputText.value = ""),

Great so now we have all of the triggers in place let’s take a closer look at the newChat function, and explore how it updates and manages the UI.

Updating the Streaming App UI as Messages are Added

The newChat function handles how messages and users appear in the UI. Messages in the UI can be divided into two groups, messages sent by the user, and messages received by the user. We want messages sent by the user to appear a certain way so that it is easier to review what they sent, and messages received by the users to appear another way. This can be done with two CSS classes, messageSent and messageReceived, which distinguishes between the messages by color.

    margin-top: 8px;
    background-color: blue;
    color: white;
    margin-top: 8px;
    background-color: white;
    color: Black;

In addition to dividing messages into two classes, we also want to add some metadata to the messages such as who sent the message and at what time they sent the message. In order to distinguish this meta information from the actual message we can add a third class for this information called messageTime.

    font-size: smaller;

With our classes defined we can now organize our newChat function to format messages accordingly. Messages received by the user should include the publisher’s messages, followed by a second line containing who sent the message and the date and time they sent the message at. Additionally, the message should be formatted with the appropriate class. Once fully formatted, the message can be returned to the event listener, which adds it to the chat box.

function newChat(message, publisher) {
       var youId = "";
       var messageClass = "messageSent";
       var messageChat = ("" + message).replace(/[<>]/g, "");
       var date = "<br><span class='messageTime'>" + new Date().toLocaleString() + "</span>";
     if (usrName === publisher) {
           youId = "<span class='youText'> (You)</span>";
           messageClass = "messageSent";
       else {
           youId = "<span class='youText'> (" + publisher + ")</span>";
           messageClass = "messageReceived";
       return "<div class='" + messageClass + "'>" + messageChat + date + youId + "</div>";
An example of the chat window built into our WebRTC live stream app. Note how messages sent by the author appear different from messages sent by other participants.

Try out the WebRTC Live Stream App with PubNub In-App Chat

The WebRTC Live stream with in-app chat enabled.

The app highlights a fully functional WebRTC stream with under half a second delay alongside a chat app that allows users to communicate with each other and the streamer, all in real-time.

Note: All code for this project is available here on GitHub. Feel free to clone the repository and launch the demo yourself.

In conclusion, adding PubNub In-App Chat to a Streaming app can greatly enhance the user experience by providing a way for viewers to interact and engage with each other in real time. Integrating PubNub into the platform is a simple and effective way to add a social element to any live stream. Whether you are streaming a live event, auction, or just having a virtual hangout with friends, a chat room can add a whole new level of excitement and engagement. If you are interested in learning more about check out some of our other content such as adding WebRTC Multiview to a live stream app or how you can add simulcast for greater viewer stability.

Feedback or Questions? Reach out to the team on TwitterLinkedIn, or reach out to our sales team.

Braden Riggs

Developer Advocate

Born and Raised in Australia and now Living in San Francisco, Braden joined the Developer Relations team in 2021 after graduating from UC San Diego with a degree in data science. Braden loves to create apps and content for the Blog, YouTube channel, and the samples GitHub. When not working you can find Braden surfing, hiking, or exploring San Francisco.

Get Started

Drive real-time interactions and engagement with sub-second latency

We are more than just a streaming solutions provider; we are a technology partner helping you build a streaming ecosystem that meets your goals. Get started for free and as you grow, we offer aggressive volume discounts protecting your margins.

Developer Resources

Explore learning paths and helpful resources as you begin development with

Copy link
Powered by Social Snap