Question
How can I customize the Chat widget using the JavaScript API?
Answer
Using our JavaScript API is a great way to make some changes and customization to your Chat widget, localized to one site or page. However, it can be tricky to figure out the syntax the first time around - so we're here to help!
The first thing to do is to figure out if you're using the Chat or Web Widget code snippet on your page. Both of these offer chat functionality, and can look the same to the visitor of the site.
Knowing the different code snippets
The Chat code snippet looks like this:
<!--Start of Zendesk Chat Script-->
<script type="text/javascript">
window.$zopim||(function(d,s){var z=$zopim=function(c){z._.push(c)},$=z.s=
d.createElement(s),e=d.getElementsByTagName(s)[0];z.set=function(o){z.set.
_.push(o)};z._=[];z.set._=[];$.async=!0;$.setAttribute("charset","utf-8");
$.src="https://v2.zopim.com/?ACCOUNT_KEY";z.t=+new Date;$.
type="text/javascript";e.parentNode.insertBefore($,e)})(document,"script");
</script>
<!--End of Zendesk Chat Script-->
The ACCOUNT_KEY
is the only unique identifier to your account. If you started with a Chat only account, this is probably the code snippet you have.
The Web Widget code snippet looks like this:
<!-- Start of Zendesk Widget script -->
<script>/*<![CDATA[*/window.zEmbed||function(e,t){var n,o,d,i,s,a=[],r=document.createElement("iframe");window.zEmbed=function(){a.push(arguments)},window.zE=window.zE||window.zEmbed,r.src="javascript:false",r.title="",r.role="presentation",(r.frameElement||r).style.cssText="display: none",d=document.getElementsByTagName("script"),d=d[d.length-1],d.parentNode.insertBefore(r,d),i=r.contentWindow,s=i.document;try{o=s}catch(e){n=document.domain,r.src='javascript:var d=document.open();d.domain="'+n+'";void(0);',o=s}o.open()._l=function(){var e=this.createElement("script");n&&(this.domain=n),e.id="js-iframe-async",e.src="https://assets.zendesk.com/embeddable_framework/main.js",this.t=+new Date,this.zendeskHost="SUBDOMAIN.zendesk.com",this.zEQueue=a,this.body.appendChild(e)},o.write('<body onload="document._l();">'),o.close()}();
/*]]>*/</script>
<!-- End of Zendesk Widget script -->
And here the SUBDOMAIN
is the unique identifier. If you started your Chat account from within your Support account, this is probably the one you are using.
However both code snippets can work in either situation, so the only way to know for sure is to open your site editor or inspect the source code to find which of the above is in place.
Adding some custom JavaScript
The most common issue with using our JavaScript API is that events are not set up to execute in the correct order. JavaScript usually runs asynchronously on a page, so without proper care it's possible the command to e.g. change the colour of the widget is executed before the widget exists. For this reason, adding the correct "ready" functions is imperative to having a reliable customization. This is also where knowing which widget code you are using will become important.
1. Chat widget code
In this case, your custom code should look something like this:
$zopim(function(){ // Custom code here });
Here, we wait for the page to finish loading, then for the Chat widget to finish loading, before adding any customization.
2. Web Widget code
Use the following:
zE(function(){ $zopim(function(){ // Custom code here }); });
In this example, we wait for the page to load, then for the Web Widget to load, and finally for the Web Widget to load the Chat functionality. After this it's safe to add any customizations you wish to the Chat widget.
The list of possible customizations can be found in our Javascript API documentation here, with each endpoint including a description and example script.
19 Comments
Hi Niall,
Quick question..!
Does this syntax work ?
Am looking to customize my web widget through JS. But am not able get hold of the syntax to make widget & JS talk to each other.
Let me know how could I make JS functions work for Web widget please.
Hey Bharath,
At first glance, it looks like you need to wrap those zopim calls in a zE(function() (see bold text below) for them to work as you're expecting.
Hi Dan,
Much Appreciated with your help.
This is a code, checking if simple code works, but cannot see its reflection on chat widget. Any thoughts on this ?
Widget color
Hey Bharath,
According to the docs, $zopim.livechat.theme.reload(); needs to be called after button.setColor is invoked. Please add that line after your line setting the color. Worth noting that the docs also list button.setColor as deprecated, you may want to consider using the latest function instead.
“$zopim.livechat.theme.setColor”
If that doesn't work, please post any messages you might be getting in your browser's console log.
Good luck!
Hi Dan,
Tried this
This is message from Console.
Hey Bharath,
I'm not sure what adrum.js is, but I think it's independent of this issue. The line you highlighted is a standard message and not an error. I just saw you have this chat module and API calls in your home_page.hbs file, could you try putting it in your document_head.hbs template? I'm not certain it will make a change, but I don't see anything else that looks wrong in what you've posted.
Hi Dan,
When I try the new web widget API's callback options they don't seem to be working as expected for migrating from the old zopim API's. Consider the following example:
1. This only prints the zopim chat session logs on change in status. The example code for web widget was picked from the documentation https://developer.zendesk.com/embeddables/docs/widget/api
2. The page that documents equivalent migrations for the API's seems to differ from the actual API documentation. Eg:
https://developer.zendesk.com/embeddables/docs/widget/chat_api_migration
In the above link it shows zE('webWidget:on', 'chat.status', (status) => {})
while in the widget api document it says zE('webWidget:on', 'chat:status', function(status<string>) {});
Note the colon instead of dot between chat and status. I've tried both and neither worked in the above example.
I've tried zopim and web widget separately too and they still haven't worked.
3. The Zendesk webwidget script for our organisation is just a single line that goes something like
Is that causing any problems?
Thanks,
Solvvy
akclsdkmsd
Hey Solvvy,
I've not checked out the newer Chat APIs yet, but it's on my to-do list to migrate. The fact that the docs differ is never a good sign. I don't actually work for Zendesk, so I won't be able to tell you what the correct method to use would be - you may want to drop a ticket to them and show them the inconsistency in the docs and see if they can get you an answer as to which of them is the correct one to use.
I don't see anything wrong with your syntax though, so it seems like its an issue with the API not delivering what you're expecting it to.
Sorry that wasn't more helpful. If you check with their Support team and get an answer that works, please come back and share, I imagine many people would be interested in the correct method!
Hi! Question about this... We have an old, deactivated implementation of Zendesk lying around on our site, using the Web Widget code snippet listed above. We are currently attempting to re-implement Zendesk on specific pages only, and the Zendesk chat experience now lists an entirely different code snippet from the two listed above:
The issue seems to be that when we turn on the chat through the Zendesk admin console, the old snippet activates and displays the chat widget on every page of our application (this is not the desired behavior). The question here, then, is: Can I remove safely the old Zendesk snippet in favor of the one listed above (which will only render on the specific pages we want the chat on), and still have zendesk chat work properly?
Looking at what is returned from the "snippet.js" in the widget code pasted above, it feels like specifically embedding either the web or chat widgets directly is no longer necessary, I just want to confirm.
My code looks like neither. From your Agent Settings Web Widget code box:
<!-- Start of winehelp Zendesk Widget script -->
<script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=blah-blah-blah"> </script>
<!-- End of winehelp Zendesk Widget script -->
No calls with zE() work. zE is undefined.
@Henry do you know if you're using a Standalone Chat account that's integrated with your Support account? If so, that may explain why your code snippet looks different on your end.
@Sean what sort of calls are you looking to make to your widget? Any additional information you have is greatly appreciated :)
Thanks!
I'm calling ...
zE(function () { zE.activate(); });
... when a component loads in my web application and the Chat widget covers the screen as a blank white div. I had to disable a popup blocker but that didn't fix the problem. Help?
Hi Donald,
Is the site your posting your code snippet public? If so, can you provide a link to where your Chat widget is hosted so we can take a look for you?
Thanks in advance!
Brett, I created a temporary fix using a call to setTimeout
setTimeout(() => { zE(function () { zE.activate(); }); },10000)
Basically, zE.activate() is getting called before the widget is rendering. Then, when the widget renders, it renders as a blank white div that covers the viewport. It takes about 5 seconds for the widget to render. You will see the page for a brief moment, then it will go blank.
I'll create a dummy page so you can see it. It only happens on mobile. You can use the Chrome dev tools with the mobile device emulator to test it.
Update: I've noticed that when the device isn't mobile, `sometimes` the chat widget will not render altogether when activate() is called before it renders.
Update 2: I've also noticed that this doesn't happen in Edge, which is strange because I thought Edge switched to Blink about a year ago.
Update 3: It worked the first time in Edge. Didn't work the second time. Same thing for the simulator. Worked the first time. I refreshed. Blank div.
https://signaturerep.com/zendeskchatwidgettest
Hey Donald,
So this is what I see on my end when I navigate to the URL you provided on my mobile device:
I've tested this in both Safari and Chrome on my mobile device and received the same results.
Are there any other steps I should be taking to try and replicate?
anyone can help me?
Widget for Web
<!-- Start of Zendesk Widget script -->
<script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=ac44704e-d4b1-4666-a1fb-1c45ba0bxxxx> </script>
<!-- End of Zendesk Widget script -->
I have entered this widget and succeeded for the website version.
for the mobile version I enter the widget code as follows:
https://v2.zopim.com/widget/livechat.html?key=ac44704e-d4b1-4666-a1fb-1c45ba0bxxxx
but it doesn't work properly ... can anyone ask for the widget code for the mobile version?
Hey Herman,
I reached out to one of our Chat experts and I've been informed that you should use the same code snippet for both Web and Mobile. Therefore you'll want to use the code snippet that's working in your web browser with your mobile version.
Hope this helps!
I couldn't find this documented anywhere else, so wanted to make a note here since this article is about required steps for using API methods.
In addition to the code above for checking that the web widget and chat widgets are loaded, the updatePath web widget api method (https://developer.zendesk.com/embeddables/docs/widget/chat#updatepath) wouldn't work without putting it inside a chatConnected method like so:
Hi Zendesk Community,
We are experiencing problems with our custom code and the various browsers customer use, specifically Edge and Internet Explorer. Any insight would be greatly appreciated as Zendesk support has been unsuccessful in providing a solution.
After further testing with IE and Edge I noticed the below.
Edge:
Internet Explorer:
Here is the code:
$(document).ready(function () {
zE(function () {
$zopim(function () {
// Calls function to get browser language
const currentLanguageCode = getCurrentLanguageCode();
// Gets language from url path
if (window.location.href.indexOf("/fr-CA") > -1) {
currentLanguageCode = "fr-ca";
}
if (currentLanguageCode == "fr-ca") {
$zopim.livechat.set({
language: "fr"
});
}
$zopim.livechat.setOnConnected(function () {
// Chat is in it's own iframe, so must access that
const chatIframe = $(".zopim iframe");
// Include Chat departments you want to display for each locale
// Department names on left side of colon must match exactly to those in Chat settings
// Translations on right side of colon - if no translation necessary, just copy department name as-is to right side
// See full list of language codes here: https://support.zendesk.com/hc/en-us/articles/203761906-Language-codes-for-Zendesk-supported-languages
const translatedDepartmentNames = {
"en-US": {
"Carriers & Racks product selection": "Carriers & Racks product selection",
"Order questions": "Order questions",
"Technical support": "Technical support",
"Active with Kids product selection": "Active with Kids product selection",
"Packs, bags & luggage product selection": "Packs, bags & luggage product selection",
"Keys & locks": "Keys & locks",
"Warranty questions": "Warranty questions"
},
"sv": {
"Orderfrågor": "Orderfrågor",
"Produktfrågor": "Produktfrågor",
"Nycklar & reservdelar": "Nycklar & reservdelar"
},
"da": {
"Produkt spørgsmål": "Produkt spørgsmål",
"Bestil spørgsmål": "Bestil spørgsmål",
"Nøgler og reservedele": "Nøgler og reservedele"
},
"fr-ca": {
"Carriers & Racks product selection": "Sélection de produits supports et porte-charges",
"Order questions": "Commandes",
"Technical support": "Support Technique",
"Active with Kids product selection": "Sélection de produits famille active",
"Packs, bags & luggage product selection": "Sélection de produits bagages et sacs",
"Keys & locks": "Clés et verrous",
"Warranty questions": "Garantie"
}
};
const currentLanguageTranslatedDepartmentNames =
translatedDepartmentNames[currentLanguageCode || "en-US"]; // default to en-US if no entry found for user locale
const allDepartments = $zopim.livechat.departments.getAllDepartments();
// Only display departments listed in
const departmentsFilteredForLocale = $zopim.livechat.departments.filter.apply(
this,
Object.keys(currentLanguageTranslatedDepartmentNames)
);
// for each department, replace the name in the select dropdown with the translated name
allDepartments.forEach(department => {
chatIframe
.contents()
.find("option[value='" + department.id + "']")
.text(currentLanguageTranslatedDepartmentNames[department.name]);
});
// also replace the selected name in the select dropdown placeholder
chatIframe
.contents()
.find(".select_placeholder")
.text(
chatIframe
.contents()
.find("select[name='department_id'] option:selected")
.text()
);
});
});
});
});
// Checks the browser language regardless of the version of the site they are on
function getCurrentLanguageCode() {
return window.navigator.languages ?
window.navigator.languages[0] :
window.navigator.userLanguage || window.navigator.language;
}
Please sign in to leave a comment.