Home Channels and inboxes How to Install the Cloud Chat Web Widget: Public, with Data, or Logged-in Area (HMAC)

How to Install the Cloud Chat Web Widget: Public, with Data, or Logged-in Area (HMAC)

Last updated on May 26, 2026

When to Use

  • You want to add the Cloud Chat widget to any page of your website

  • You want to automatically pass contact data (name, email, phone, attributes) without the client typing

  • You want to validate the user's identity (HMAC) to prevent impersonation

  • You want to allow multiple simultaneous conversations and access to history within the widget

  • You want to restrict the widget to specific domains (e.g., production only)


Prerequisites

  • Be logged in as admin on Cloud Chat

  • Access to the source code of the website where the widget will be installed

  • For Scenario 3 (logged-in area with HMAC): a custom backend to generate the identifier_hash β€” it cannot be done on the frontend (exposes the secret key)


About this Tutorial

This article covers the full cycle of installing the Cloud Chat Web Widget. Before following the coding steps, you need to decide which of the 3 scenarios fits your use case β€” they have very different requirements and complexity.

Which scenario is yours?

Scenario When to use Pass customer data? Needs HMAC?
1. Public widget (no data) Public site / landing page / blog. The customer enters their name and email to start the chat. ❌ No ❌ No
2. Widget with data, outside logged-in area Pages that already know the contact but do not require strong authentication (e.g., single link sent via email/CRM, post-registration form). βœ… Yes ❌ No
3. Logged-in area widget (with HMAC) Customer portal, internal dashboard, authenticated app. Any scenario where user login is required to access. βœ… Yes βœ… Mandatory

If your case is Scenario 3 (logged-in area), you must configure HMAC. Without it, the conversation will not be created.

The contact's custom attribute must be created beforehand β€” see Creating custom contact and conversation fields.


Common Step β€” Create the Website Inbox

Before configuring any scenario, you need to create a Website-type inbox in Cloud Chat. The process is the same for all 3 scenarios.

1. Access the Inboxes Screen

In the Cloud Chat dashboard, go to Settings β†’ Inboxes and click on the Add Inbox button (top right corner).

2. Choose the Website Channel

Select the Website card from the available channels.

3. Configure the Website Channel

Fill in the fields:

  • Site Name β€” name shown to the customer (e.g., "Cloud Humans")

  • Website Domain β€” domain where the widget will run (e.g., cloudhumans.com)

  • Widget Color β€” primary color of the button and header

  • Welcome Title β€” initial widget title (e.g., "Hello!")

  • Welcome Message β€” greeting message

  • Activate Channel Greeting β€” whether to send an automatic message at the start of chat

Click Create Inbox.

4. Add Agents

Select the agents who will have access to this inbox. As an administrator, add yourself if you want to see all conversations.

Click Add Agents.

5. Script Configuration

On the final screen (β€œYour inbox is ready!”), Cloud Chat displays the basic installation script for the widget. However, other configuration options are available depending on your scenario.

Click More Settings. In this section, you'll see the three available script options for installation, which we will explain below.

Done. Now proceed to the scenario that applies to your case (1, 2, or 3 below) and follow the specific instructions for each.


Scenario 1 β€” Public Web Widget (no customer data passing)

Use when the widget is on a public page (landing, blog, institutional site). The customer types their name/email/phone at the start.

How to Install

Paste the script copied in the Common Step (Step 5) just before the closing </body> tag of your page's HTML:

That's it. This scenario requires nothing beyond the base script. Do not call setUser(), do not pass identifier_hash. The customer fills in their data in the widget's initial form.


Scenario 2 β€” Web Widget passing customer data, outside logged-in area

Use when you already know the contact but the page does not require login. Examples:

  • Unique link sent via email or WhatsApp with the identifier in the URL

  • Post-registration page (customer just filled out a form)

  • Page accessed via CRM campaign deep link

Here, you want to pre-fill name, email, phone, and custom attributes without the customer typing.

How to Install

⚠️ The first argument of setUser(...) is the identifier β€” it must be unique per user (internal ID, database UUID, etc). If you leave the identifier fixed (hardcoded, placeholder, copy-paste example), Cloud Chat will merge all accesses as the same contact β€” merging tickets from different people and irreversibly breaking history.

Before deploying to production, confirm with your engineering team that the identifier is being dynamically populated with the actual user ID.

You must pass at least email or phone β€” these are the identifiers Cloud Chat uses to match contacts.


Scenario 3 β€” Logged-in Web Widget (with HMAC + optional multiple conversations)

Use when the widget is inside a logged-in area (client portal, dashboard, authenticated app). HMAC is mandatory here.

This scenario is also the only one where enabling multiple conversations + history makes sense.

3.1 β€” How HMAC Works

Validation uses HMAC SHA-256: a code generated from the user's identifier combined with a secret key (token) of the inbox.

The generation of identifier_hash is the client's responsibility. It needs to happen on the backend (server), never in the browser. If the secret key leaks in the frontend, protection ceases to exist. Cloud Humans provides the token per inbox; implementing the hash calculation and passing it to the widget is the client's technical team's responsibility.

3.2 β€” Copy the inbox token

In Settings β†’ Inboxes β†’ (your Website inbox) β†’ Advanced Settings β†’ User Identity Validation β†’ Copy.

This token is secret β€” store it only in your backend, never in the frontend.

3.3 β€” Calculate identifier_hash on backend

When the user authenticates in your system, the backend calculates:

identifier_hash = HMAC_SHA256(inbox_token, identifier)

Where identifier is the user's unique ID (internal UUID, corporate email, etc).

Server-side examples:

// Node.js
const crypto = require('crypto');
const hash = crypto
  .createHmac('sha256', '<inbox-token>')
  .update('<identifier>')
  .digest('hex');
# Python
import hashlib, hmac
hash = hmac.new(b'<inbox-token>', b'<identifier>', hashlib.sha256).hexdigest()
// PHP
$identifier_hash = hash_hmac('sha256', '<identifier>', '<inbox-token>');

3.4 β€” Send the hash to the widget via setUser

<script>
  (function(d,t) {
    var BASE_URL="https://cloudchat2.cloudhumans.com";
    var g=d.createElement(t),s=d.getElementsByTagName(t)[0];
    g.src=BASE_URL+"/packs/js/sdk.js";
    g.defer = true;
    g.async = true;
    s.parentNode.insertBefore(g,s);

    g.onload=function(){
      window.cloudchatSDK.run({
        websiteToken: 'YOUR_TOKEN_HERE',
        baseUrl: BASE_URL
      });

      window.addEventListener('cloudchat:ready', function() {
        window.$cloudchat.setUser('<user-identifier>', {
          identifier_hash: '<hash-generated-backend>',
          email: '[email protected]',
          name: 'JoΓ£o da Silva',
          phone_number: '+5511999999999'
        });
      });
    }
  })(document,"script");
</script>

3.5 β€” Force validation in the inbox

In Advanced Settings, enable "Force user identity validation". Requests without a valid identifier_hash are rejected.

Activate "Force validation" only after your backend is sending the correct identifier_hash. If activated prematurely, conversations without the hash will be rejected and the chat will stop working. Test first in a test inbox.

Best practices:

  • Use a stable identifier β€” never change the ID of an existing user

  • Do not expose the HMAC token in the frontend

  • Generate the hash always on backend and send only during widget initialization

  • Regenerate the identifier_hash every time the widget loads for an authenticated user

3.6 β€” (Optional) Enable multiple conversations and history

With HMAC enabled, you can activate the feature of multiple conversations + history: the same user can have several open conversations simultaneously and see the history of closed conversations within the widget.

Useful for SaaS, B2B, or e-commerce with high repurchase/retargeting.

How the user sees: the widget will now display two tabs β€” Active Conversations (open) and Conversation History (closed, with date range and ticket ID search; loads 5 at a time).

Demonstrative videos:

How to enable:

  1. In Cloud Chat dashboard, go to Inboxes β†’ (your Website inbox) β†’ Settings

  2. Enable the Multiple conversations per user flag

  3. Copy the new script displayed after activation β€” it already includes user_id and identifier_hash in the correct format

  4. Replace the current page script with the new one

The multiple conversations and history feature depends on HMAC being active and working. Do not enable it on public widget (Scenario 1) or non-logged-in widget (Scenario 2) β€” without identity validation, anyone can access another user's history.


Domain Validation (optional, all scenarios)

Configure the domains where the widget can operate β€” useful to prevent usage outside authorized domains (staging, unauthorized third parties).

In Inboxes β†’ (your inbox) β†’ Settings, under the Domain Validation section:

Setting Behavior
Empty field No restrictions β€” works on any domain
example.com Allows use only on this domain
*.example.com Allows use on all subdomains (e.g., app.example.com, login.example.com)

How to Test

  1. Open the page with the widget installed

  2. Check if the widget appears at the corner of the screen

  3. Scenarios 2 and 3: verify that name, email, phone, and attributes already appear pre-filled without customer input

  4. Scenarios 2 and 3: test with at least 2 different users β€” open the widget with one, then with another, and check if they appear as separate contacts (not merged into one). If they appear merged, the identifier is fixed β€” fix it before deploying to production

  5. Scenario 3: test with an invalid identifier_hash and verify that the widget rejects the request when "Force validation" is enabled

  6. Scenario 3 with multiple conversations: open two tickets in parallel and check that they appear as separate conversations inside the widget


Frequently Asked Questions

What happens if there is already previous contact information?

The new data sent via script overwrites the old data. The most recent information prevails.

What if I make a mistake in a custom field name?

No error is thrown. The incorrect field is silently ignored. Only existing fields are updated.

Can I pass conversation attributes as well?

Not at the moment. Passing custom conversation attributes has not been released in version 0 due to technical limitations. Use the initial conversation form as an alternative.

What formatting does the widget accept?

The Widget accepts most Markdown formats:

  • Bold / Strikethrough / Italic

  • Code block

  • Links

  • Images

  • Bullet points

Can I use HMAC without enabling multiple conversations?

Yes. HMAC is an independent security layer β€” you can enable only HMAC (Scenario 3, steps 3.1 to 3.5) without enabling multiple conversations (step 3.6). The reverse is not recommended.

Can I use this in mobile apps?

Yes, via WebView. See How to integrate the Web Widget into mobile apps.


Notes