The headless web SDK gives you the flexibility to extend and customize your company's support experience according to your needs. It contains all our familiar web SDK features and provides the ability to build out the UI and UX to support them.
Installing and using the headless web SDK requires the support of your organization's web development team. To perform a successful integration and achieve optimal performance, Google recommends involving your qualified personnel.
In the context of software development, "headless" refers to a decoupled architecture where the frontend presentation layer (the "head") is separated from the backend logic and capabilities. In a headless architecture the backend, also known as the "headless" part, provides APIs that let you use its features and services.
An example is custom workflow automation. When an end-user initiates a chat, the on("chat.message")
event is triggered. You can define custom automation
triggers based on specific chat messages you've received. For example, if an
end-user types "Escalate" in the chat, the event handler can automatically
escalate the chat session to a higher-level support team, providing prompt
attention to critical issues.
This guide walks you through the SDK's installation process, integration capabilities, and usage. For details about using the API, see the Headless web SDK API documentation . A list of available events can be found on the events page .
Install the headless web SDK
To install the headless web SDK, use the following code snippet in your project:
npm
install
@ujet/websdk-headless
--save
Use the headless web SDK
To use the headless Web SDK, you can follow the example code provided:
import
{
Client
}
from
"@ujet/websdk-headless"
const
client
=
new
Client
({
...
})
async
function
authenticate
()
{
const
resp
=
await
fetch
(
"/your-auth-endpoint"
)
const
data
=
await
resp
.
json
()
return
{
token
:
data
.
token
}
}
const
client
=
new
Client
({
companyId
:
"YOUR-COMPANY-ID"
,
tenant
:
"YOUR-TENANT-NAME"
,
authenticate
:
authenticate
,
})
// const company = await client.getCompany()
// const menus = await client.getMenus()
The Client class accepts several options (you can customize according to your requirements):
interface
ClientOption
{
companyId
:
string
;
authenticate
:
()
=
>
Promise<TokenResponse>
;
tenant
?:
string
;
host
?:
string
;
lang
?:
string
;
bridge
?:
string
;
cobrowse
?:
{
enabled
:
boolean
;
messages
?:
CobrowseMessages
;
api
?:
string
;
license
?:
string
;
trustedOrigins
?:
string
[];
capabilities
?:
string
[];
registration
?:
boolean
;
redactedViews
?:
string
[];
unredactedViews
?:
string
[];
};
}
Enable logging
During implementation and testing it might be necessary to gather additional
information in the console log. To enable logging for the headless SDK, import Logger
and consoleLoggerHandler
by adding the following code to your web application:
import
{
Logger
,
consoleLoggerHandler
}
from
'@ujet/websdk-headless'
Logger
.
addHandler
(
consoleLoggerHandler
)
Enable Screen Share
The headless web SDK offers a built-in integration with Screen Share. The SDK provides a default UI, but you can customize it by providing your own CSS.
The default template is:
<dialog
open
class="cobrowse-dialog">
<h1>$title</h1>
<div
class="cobrowse-dialog_content">$content</div>
<div
class="cobrowse-dialog_footer">
<button
class="cobrowse-dialog_allow
js-cobrowse-allow">$allow</button>
<button
class="cobrowse-dialog_deny
js-cobrowse-deny">$deny</button>
</div>
</dialog>
The template is wrapped by a <div>
tag:
<div class="cobrowse-wrapper">${template}</div>
You can add CSS style according to the previous template's class names.
Custom template
You can also provide a custom template with class="cobrowse-template"
, for
example:
const COBROWSE_CONSENT_TEMPLATE = '
<script class="cobrowse-template" type="text/template">
<div class="cobrowse">
<div class="cobrowse-title">$title</div>
<div class="cobrowse-content">$content</div>
<div class="cobrowse-footer">
<button class="cobrowse-deny js-cobrowse-deny">$deny</button>
<button class="cobrowse-allow js-cobrowse-allow">$allow</button>
</div>
</div>
</script>
'
const client = new Client({
companyId: "YOUR-COMPANY-ID",
tenant: "YOUR-TENANT-NAME",
authenticate: authenticate,
cobrowse: {
template: COBROWSE_CONSENT_TEMPLATE,
...
},
...
})
Variables $title
, $content
, $deny
, and $allow
will be replaced
automatically.
Custom messages
The default messages for the $title
, $content
, $deny
, and $allow
variables are:
{
"confirmSessionTitle"
:
"Co-browse Session Request"
,
"confirmSessionContent"
:
"Do you want to share your current screen with the agent?"
,
"endSessionText"
:
"End Co-browse Session"
,
"confirmRemoteControlTitle"
:
"Remote Access Request"
,
"confirmRemoteControlContent"
:
"The agent would like to have access to your currently shared screen to further assist you. Do you want to allow this?"
,
"confirmFullDeviceTitle"
:
"Screen Share Request"
,
"confirmFullDeviceContent"
:
"Do you want to share your full screen with the agent? The agent will not be able to control anything on the screen."
,
"allowText"
:
"Allow"
,
"denyText"
:
"Deny"
}
You can customize the message using cobrowse.messages
:
const
client
=
new
Client
({
companyId
:
"YOUR-COMPANY-ID"
,
tenant
:
"YOUR-TENANT-NAME"
,
authenticate
:
authenticate
,
cobrowse
:
{
enabled
:
true
,
messages
:
{
confirmSessionTitle
:
"..."
,
confirmSessionContent
:
"..."
,
endSessionText
:
"..."
,
confirmRemoteControlTitle
:
"..."
,
confirmRemoteControlContent
:
"..."
,
confirmFullDeviceTitle
:
"..."
,
confirmFullDeviceContent
:
"..."
,
allowText
:
"..."
,
denyText
:
"..."
,
}
}
})
Custom data configuration
The custom_data option lets you pass arbitrary key/value data to the web SDK.
Usage
You can provide custom data as either an object (unsigned) or a string (signed) when creating a chat:
interface
ChatRequest
{
lang?:
string ;
trigger_id?:
string ;
ticket_id?:
string ;
email?:
string ;
greeting?:
string ;
cobrowsable?:
boolean ;
custom_data?:
{
signed?:
string ;
unsigned?:
Record<string,
any> ;
}
;
}
See the following example:
const
custom_data
=
{
unsigned:
{
version:
{
label:
'Version'
,
value:
'1.0.0'
}
}
,
signed:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
//
JWT
or
other
signed
payload }
try
{
const
chat:
Chat
=
await
client.createChat (
123
,
{
custom_data
})
}
catch
(
error )
{
//
handle
error }
External chatbot transfer
There are some cases where you might want to maintain history and interactions
from other chat providers. You can do this by using the custom_data object
.
See the following example:
const
custom_data
=
{
unsigned:
{
external_chat_transfer:
{
greeting_override:
"Please hold while we connect you with a human agent."
,
agent:
{
name:
"Agent Name"
,
avatar:
"https://ujet.s3.amazonaws.com/default-virtual-agent-avatar-1.png"
}
,
transcript:
[
{
sender:
"agent"
,
timestamp:
"2021-03-15 12:00:00Z"
,
content:
[
{
type:
"text"
,
text:
"Hello! How can I help you today?"
}
,
{
type:
"buttons"
,
buttons:
[
{
label:
"Create New Order"
,
selected:
false
}
,
{
label:
"Check Order Status"
,
selected:
true
}
,
{
label:
"Check Account Balance"
,
selected:
false
}
,
]
}
]
}
,
{
sender:
"end_user"
,
timestamp:
"2021-03-15 12:00:15Z"
,
content:
[
{
type:
"text"
,
text:
"Check Order Status"
}
]
}
,
{
sender:
"agent"
,
timestamp:
"2021-03-15 12:00:16Z"
,
content:
[
{
type:
"text"
,
text:
"I can help you with that, what's your order number?"
}
]
}
,
{
sender:
"end_user"
,
timestamp:
"2021-03-15 12:00:20Z"
,
content:
[
{
type:
"media"
,
media:
{
type:
"image"
,
url:
"https://ujet.s3.amazonaws.com/default-virtual-agent-avatar-1.png"
}
}
]
}
]
}
}
,
signed:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
//
JWT
or
other
signed
payload }
try
{
const
chat:
Chat
=
await
client.createChat (
123
,
{
custom_data
})
}
catch
(
error )
{
//
handle
error }