Typing Indicators in Chat Powered by PubNub Signals

4 min read Adam Bavosa on Aug 14, 2019

Our customers have spoken, and we have responded with PubNub Signals. The new Signals feature is a part of PubNub’s Publish-Subscribe API for sending real-time data between devices. Signals are very similar to Publishes with some intuitive trade-offs to save you money.

Let’s say you need to send a constant stream of small sized, non-critical messages. Something like a frequent temperature sensor update from an IoT device, or a GPS coordinate stream in a ride-share app, or a typing indicator signal in a chat app. This is the perfect opportunity to utilize PubNub Signals instead of PubNub Publishes.

What is PubNub’s PubSub Messaging?

Pub/Sub allows developers to send messages, with a payload of up to 32KB, to any active subscribers. Publishers can be any device that knows TCP. Published messages are replicated to all PubNub global data centers. Published messages can be stored in PubNub History, or invoke a Function, or Mobile Push notification.

What is a PubNub Signal?

A Signal is the same as a PubNub Publish except it is small, with a payload of up to 64 bytes. Signals are replicated to all global data centers like Publishes. However they are not stored in History for a later fetch; only the most recent Signal message can be fetched later.

They can’t invoke external mobile push notifications, although they may be eligible to use Functions (speak to Support or your Account rep to set this up). Signal pricing is, as a result, far lower, making signals ideal for high-volume streams of data.

Why Use Signal Instead of Publish?

PubNub Signals include the same reliability and latency as PubNub Publishes, but they are intended for data stream messaging, where the stream of data is more important than the exact content of each individual message. Examples would include chat app typing indicators, live GPS location update stream, and live sensor update streams from IoT devices.

Chat App Typing Indicator Demo

Open the HTML page of the simple chat demo. The chat includes Typing Indicators powered by PubNub Signals. This will make invoking typing indicators inexpensive even when your chat app is being used at scale.

Using PubNub Publishes for Typing indicators may not be the best choice at scale: the extra overhead for things like global replication and history storage are not necessary for  simply displaying a typing indicator.

Be sure to get your own free PubNub API keys to put in this file. Get your API keys now in the admin dashboard.

The HTML File will not run unless you replace the YOUR_PUBNUB_PUBLISH_KEY / YOUR_PUBNUB_SUBSCRIBE_KEY with your free API key.

<!-- Chat in 10 lines of JavaScript code using PubNub JavaScript V4 SDK -->
<!DOCTYPE html>
<html lang="en">

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="Example of a JavaScript chat app using PubNub JavaScript V4 SDK.">
    <meta name="keywords" content="JavaScript,PubNub,Chat,chat-room,chatting,SDK,PubSub-sdk,tutorial">
    <title>JavaScript Chat | PubNub</title>

    <h1>Chat Example with Typing Indicators</h1>
    <h2>Typing Indicators using PubNub Signals</h2>
        <a href="">
            <img src="" alt="Powered By PubNub" width="150">
            <p>Enter chat and press enter.</p>
            <input id="input" placeholder="Your Message Here" />
            <p id="typing-indicator" style="visibility:hidden;">Is Typing:<span id="typing-user-id"></span></p>
            <p>Chat Output:</p>
            <div id="box"></div>
<script src=""></script>
(function() {
    const pubnub = new PubNub({ publishKey: 'YOUR_PUBNUB_PUBLISH_KEY', subscribeKey: 'YOUR_PUBNUB_SUBSCRIBE_KEY' }); // Your PubNub keys here. Get them from

    let box = document.getElementById("box"),
        input = document.getElementById("input"),
        typingIndicator = document.getElementById("typing-indicator"),
        typingUserId = document.getElementById("typing-user-id");
        chatMessageChannel = 'chat-signals-example',
        timeoutCache = 0,
        isTyping = false,
        isTypingChannel = 'is-typing';

    let hideTypingIndicator = () => {
        isTyping = false; = "visibility:hidden;";

    pubnub.subscribe({ channels: [chatMessageChannel, isTypingChannel] }); // Subscribe to a channel.

        message: function(m) {
            hideTypingIndicator(); // When a message has been sent, hide the typing indicator
            box.innerHTML = ('' + m.message).replace(/[<>]/g, '') + '<br>' + box.innerHTML; // Add message to page.
        signal: function(s) {
   = "";
            typingUserId.innerText = s.publisher; // the UUID of the user who is typing
            timeoutCache = setTimeout(hideTypingIndicator, 10000) // 10 seconds

            if (s.message === '0') {

    input.addEventListener('keyup', function(e) {
        // Publish new PubNub message when return key is pressed.
        if ((e.keyCode || e.charCode) === 13 && input.value.length > 0) {
                channel: chatMessageChannel,
                message: input.value

            input.value = '';

        const inputHasText = input.value.length > 0;

        // Publish new PubNub signal: Typing Indicator ON (1) or OFF (2)
        if ((inputHasText && !isTyping) || (!inputHasText && isTyping)) {
            isTyping = !isTyping;
                channel: isTypingChannel,
                message: inputHasText ? '1' : '0'



Here is what the demo looks like in 2 browser windows, one is incognito mode so there is a second user ID shown in in the typing indicator UI.

Typing Indicator Demo with PubNub Signals