MixdeskHelp Center
Skip to content

Developer Documentation

JavaScript Chat Widget

Last updated Nov 6, 2025

On this page

Hide the default chat button

To hide Mixdesk’s built-in chat button, use _MIXDESK('withoutBtn');.

Example

<!-- Mixdesk embed code -->
<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    // Enable no-button mode here
    _MIXDESK('withoutBtn');
</script>

Open the chat window

You can control the Mixdesk chat window from your own code.

After the widget initializes, call _MIXDESK('showPanel') to open the chat window.

Note

  • Calling this before initialization completes will not work.
  • To open the window immediately after initialization, use the initialization callback.

Example

<!-- Bind showPanel directly to an HTML element -->
<a href="javascript:void(0)" onclick="_MIXDESK('showPanel')">Contact support</a>
<!-- Or call it from JavaScript -->
<script>
    _MIXDESK('showPanel');
</script>

Initialization callback

To run code after the widget finishes loading, use _MIXDESK('allSet', callback).

Note

  • Register this before initialization. It does not need to immediately follow the embed code.

Example

<!-- Your code -->
<script type='text/javascript'>
    function yourFunction() {
        // Add your own logic here
        console.log('MixdeskWidget initialization complete.');
    }
</script>
<!-- Mixdesk embed code -->
<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    // Initialization callback
    _MIXDESK('allSet', yourFunction);
</script>
<script type='text/javascript'>
    // With manual initialization, call allSet at the appropriate point in your logic
    // Register this before Mixdesk initializes
    _MIXDESK('allSet', yourFunction);
    _MIXDESK('init');
</script>

Manual initialization

After loading the widget, call _MIXDESK('init') from JavaScript to initialize it manually.

Usage

  1. Add _MIXDESK('manualInit'); immediately after the embed code to prevent automatic initialization when downloading finishes.
  2. When ready, call _MIXDESK('init') in your JavaScript.

Note

  • _MIXDESK('manualInit'); must immediately follow the embed code.
  • Without setting _MIXDESK('manualInit');, you cannot use _MIXDESK('init');.
  • If you call _MIXDESK('init') before the code finishes downloading, it runs after the download completes.

Example

<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    // Enable manual mode here, immediately after the embed code
    _MIXDESK('manualInit');
</script>
<!-- Your JavaScript code -->
<script>
    // Call manual initialization at the appropriate time in your code
    _MIXDESK('init');
</script>
<!-- Adapt this pattern to your application. May the force
 be with you -->

Open a conversation automatically

To open the chat window after loading, use:

Example

<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    // Call showPanel after initialization
     _MIXDESK('allSet', function(){
       _MIXDESK('showPanel');
    });
</script>

Pass contact information

Default contact fields

tel // Phone number format: +country calling code followed by the number, e.g: +86138XXXX1234, Otherwise, the value cannot be passed.
name // Name
email // Email
comment // Notes

Configure custom contact fields in workspace settings.

Without encryption

Chat widget

Use the _MIXDESK('metadata', {}) API to pass the information automatically. Call it only after widget initialization.

<script type='text/javascript'>
     function doSomething () {
         // Pass contact information
         _MIXDESK('metadata', {
            name: 'test',
            }
         );
     }
</script>

Use double quotes around both keys and values in metadata.

/standalone-priv.html?eid=EnterpriseID&metadata=
{"name":"Test","email":"123456@mail.com"}

Note: Escape metadata values containing & or = before passing them.

&  %26
=  %3D

Correct:

/standalone-priv.html?eid=EnterpriseID&metadata=
{"name":"Test","email":"123456@mail.com","url":"http://mixdesk.com?a%3D1%26b%3D2"}

Incorrect:

/standalone-priv.html?eid=EnterpriseID&metadata=
{"name":"Test","email":"123456@mail.com","url":"http://mixdesk.com?a=1&b=1"}

With encryption

Encryption algorithm

AES Mode: CBC
Padding: PKCS7Padding
Block size: 128
Key: workspace ID
IV: workspace ID
Output: Hex
Character set: UTF-8
Verify the encrypted result: http://tool.chacuo.net/cryptaes
Encrypt&Decryption code reference: https://gist.github.com/ksxkq/00a21e18bcadb86512a023f95c4ecb13

Example

1.Prepare the data as a JSON object:
 {"name":"value"}

2.Encrypt the data using the algorithm below. In this example, the key and IV are 2bab953cb29e7a1e3be20ab97d5c675b. The encrypted result is:
 cd0caf04a1c6ff63d7951cd5e2016167066c6032e2fd2c8ae543a02d6145e897

3.Use in the chat widget
 function setEncryptedmetadata () {
  _MIXDESK('encryptedMetadata', 'cd0caf04a1c6ff63d7951cd5e2016167066c6032e2fd2c8ae543a02d6145e897');
 }

Set a unique contact identifier

After calling _MIXDESK('clientId', 'UNIQUE_CONTACT_ID') to set the user identifier, the widget instance can initialize only once.

For login flows, wait until login has completed before running _MIXDESK initialization code (load the widget after login). Otherwise, the widget cannot be initialized again.

The unique contact identifier comes from your own user system.

Use _MIXDESK('clientId', 'UNIQUE_CONTACT_ID') to synchronize it.

Note

  • The identifier must be a string of 6–32 characters. Generate a unique value for each contact. Reusing identifiers can expose one customer’s messages to another.

Chat widget Example

<!-- Mixdesk embed code -->
<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script',    a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s););
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    // Set clientId: uncomment and use the contact ID from your own system
    // _MIXDESK('clientId', 'Every contact must have a unique identifier');
</script>

Handle the chat-window close event

Receive an event when the visitor selects the chat-window close button.

Example

<!-- Your code -->
<script type='text/javascript'>
    function handleBeforeCloseWindow() {
        console.log('Close selected')
    }
</script>
<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    //Callback after selecting Close
    _MIXDESK('beforeCloseWindow', handleBeforeCloseWindow);
</script>

Get unread messages

The default chat button shows an unread count and a preview of the most recent unread message.

In no-button mode, use the _MXIDESK('getUnreadMsg', callback); API to retrieve this data through the callback parameters and display it in your own interface.

Note

  • Register this before initialization; it need not immediately follow the embed code.
  • Unread-message storage uses localStorage, so it is unavailable in browsers older than IE8.

Example

<div>
    <div>Data from the unread-message API</div>
    <div>Unread message count: <b id="unreadNum">0</b></div>
    <div>Latest unread message content:<b id="unreadMsg"></b></div>
</div>
<!-- Simple unread-message handling example -->
<script>
    /**
     * [Handle unread messages]
     * @param  {[string, object]} msg [string: 'hasBeenRead',
 object: Unread message data]
     */
    function yourFunction(msg) {
        var text = '',
            num = 0;
        if (msg === 'hasBeenRead') { // Messages have been read
            num = 0;
        } else if (typeof(msg) === 'object') {
            var unreadNum = document.getElementById('unreadNum').innerHTML,
                lastMsg = msg[msg.length - 1];
            num = isNaN(+unreadNum) ? msg.length : +unreadNum + msg.length;
            // content_type  is the message type: 
            // text(text), photo (image), file (file)
            // content  is the message content
            if (lastMsg.content_type === 'text') {
                // Text messages may contain emoji images; account for their paths
                // Convert images in text messages to text'[emoji]'
                text = lastMsg.content.replace(
                    /<img [^>]*src=['"]([^'"]+)[^>]*>/gi, '[emoji]'
                );
            } else if (lastMsg.content_type === 'photo') {
                text = '[image]';
            } else if (lastMsg.content_type === 'file') {
                text = '[file]';
            } else {
                text = '[New message]';
            }
        }
        // Unread message count
        document.getElementById('unreadNum').innerHTML = num;
        // Latest message content
        document.getElementById('unreadMsg').innerHTML = text;
    }
</script>
<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    // Get unread messages
    _MIXDESK('getUnreadMsg', yourFunction);
</script>

Follow the browser language

Include the languageLocal parameter to control whether the widget follows the browser language at initialization.

Example configuration:

<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    //Use this configuration for English
    _MIXDESK('language','en');
    //Use this configuration to follow the browser language
    _MIXDESK('languageLocal','true')
</script>

When enabled, the widget chooses its language in this order:

  1. First, the browser language. If unsupported, continue to the next option.
  2. Next, the language specified for the channel. If missing or invalid, continue to the next option.
  3. Finally, the channel’s default language, which is Simplified Chinese.

Handle the widget close event

Receive an event when the customer selects the widget’s close button.

Example

<!-- Your code -->
<script type='text/javascript'>
function handleBeforeCloseWindow() {
 console.log('Close selected')
 }
</script>
<script type='text/javascript'>
   (function(a, b, c, d, e, j, s) {
         a._t = d;
        a[d] = a[d] || function() {
            (a[d].a = a[d].a || []).push(arguments)
        };
        j = b.createElement(c),
            s = b.getElementsByTagName(c)[0];
        j.async = true;
        j.charset = 'UTF-8';
        j.src = 'https://chat.mixdesk.com/entry.js';
        s.parentNode.insertBefore(j, s);
    })(window, document, 'script', '_MIXDESK');
    _MIXDESK('entId', 'YOUR_WORKSPACE_ID');
    //Callback after selecting Close
    _MIXDESK('beforeCloseWindow', handleBeforeCloseWindow);
</script>

Related articles

Still need help?

Contact support@mixdesk.com for help with your setup.