The Libredesk live chat widget embeds on any website as a single script tag. Visitors can start conversations anonymously, or you can verify their identity with a server-signed JWT so the widget loads with their profile attached.
Create a live chat inbox
1. Go to Admin, then Inboxes, then New inbox, then Live chat. Fill in the name, brand name and website URL.
2. Set the launcher colour, position, logo, greeting message and home screen under the Appearance and Messages tabs. Changes go live as soon as you save.
3. Open the Installation tab and copy the script snippet. Paste it before the closing body tag on every page where the widget should appear.
Install the widget
The anonymous snippet looks like this.
<script>
window.LibredeskSettings = {
baseURL: 'https://support.example.com',
inboxID: 'YOUR_INBOX_UUID'
};
</script>
<script async src="https://support.example.com/widget.js"></script>
baseURL is the URL of your Libredesk instance. inboxID is the UUID shown on the inbox's Installation tab. Anyone visiting the page can now open the widget. Every session is a new anonymous visitor unless you add identity verification.
Identity verification
If users are already signed in to your product, pass a signed JWT so the widget loads with their existing Libredesk contact. Without it, the widget cannot tell a returning user apart from a new visitor on a new device.
Your server signs a JWT with the inbox secret key, set under the Security tab. Your page passes that JWT to the widget as userJWT. Libredesk verifies the signature and then matches or creates the contact by external_user_id. The algorithm is HS256. The secret never leaves your server.
{
"external_user_id": "your_app_user_123",
"email": "[email protected]",
"first_name": "John",
"last_name": "Doe",
"phone_number": "9876543210",
"phone_number_country_code": "IN",
"exp": 1735689600,
"contact_custom_attributes": {
"plan": "premium",
"company": "Acme Inc"
}
}
Required fields are external_user_id (a stable unique ID from your system, used to match returning users), email, first_name and exp (a Unix timestamp in seconds). Optional fields are last_name, phone_number, phone_number_country_code (ISO 3166-1 alpha-2, for example IN) and contact_custom_attributes, which is written to the contact record on login.
Sign the token on your server.
import jwt, time
payload = {
"external_user_id": "your_app_user_123",
"email": "[email protected]",
"first_name": "John",
"exp": int(time.time()) + 3600,
}
token = jwt.encode(payload, SECRET, algorithm="HS256")
const jwt = require('jsonwebtoken');
const token = jwt.sign({
external_user_id: 'your_app_user_123',
email: '[email protected]',
first_name: 'John',
exp: Math.floor(Date.now() / 1000) + 3600,
}, SECRET, { algorithm: 'HS256' });
Never put the inbox secret in client-side code. Sign the JWT on your server and inject it into the page at render time, or fetch it from an authenticated endpoint.
Then pass it to the widget.
<script>
window.LibredeskSettings = {
baseURL: 'https://support.example.com',
inboxID: 'YOUR_INBOX_UUID',
userJWT: 'YOUR_SIGNED_JWT_TOKEN_HERE'
};
</script>
<script async src="https://support.example.com/widget.js"></script>
JavaScript API
Once the widget loads, window.Libredesk exposes these methods.
Libredesk.show()- open the widgetLibredesk.hide()- close the widgetLibredesk.toggle()- toggle open and closedLibredesk.setUser(jwt)- log a user in after page loadLibredesk.logout()- clear the session and reset to anonymousLibredesk.onShow(fn)- callback fired when the widget opensLibredesk.onHide(fn)- callback fired when the widget closesLibredesk.onUnreadCountChange(fn)- callback fired with the unread message count
Conversation continuity
Contacts do not have to stay in the live chat. If they leave before the conversation is finished, Libredesk can email them any unread messages. Replies to that email thread are added back to the same live chat conversation.
offline_threshold- how long agents must be offline before a fallback email is sent, for example10mmax_messages_per_email- maximum messages per email. Anything more goes in a new emailmin_email_interval- minimum time between fallback emails for the same conversation
Security
Under the Security tab, list the domains allowed to embed the widget. Requests from other origins are rejected. Wildcards are supported, for example example.com, *.example.com or staging.example.com. Leaving it empty allows all origins, so always set it in production.
You can also block specific IPs or CIDR ranges from opening the widget, for example 192.168.1.0/24, 10.0.0.1 or 2001:db8::/32.
Session duration controls how long a widget session stays authenticated before the JWT has to be verified again. The default is 10h. The format accepts s, m and h.