January 27th, 2023
Adding Zendesk livechat on a react app might not be as straghtforward as it looks.
The example uses state to check if $zopim is ready to interact (isZopimReady).
Once that state is true, $zopim is ready to be interacted with. The best way is to have a useEffect hook listening to isZopimReady and run the desired configurations on $zopin.
import React, { FC, useEffect, useState } from "react";
import { useInterval } from "usehooks-ts";
import useScript from "hooks/useScript";
declare const $zopim: any;
interface ZendeskProps {
firstName?: string | null;
lastName?: string | null;
email?: string | null;
}
const Zendesk: FC<ZendeskProps> = ({ firstName, lastName, email }) => {
const status = useScript("https://static.zdassets.com/ekr/snippet.js?key=8f60d464-1c48-48a6-8d14-25f47c389e59", {
id: "ze-snippet",
});
const [isZopimReady, setIsZopimReady] = useState(false);
/**
* used to set livechat configurations
* once isZopimReady is true
*/
useEffect(() => {
if (isZopimReady) {
$zopim(() => {
$zopim.livechat.button.setOffsetVertical(80);
$zopim.livechat.button.setOffsetHorizontal(60);
$zopim.livechat.button.setPosition("br");
if (firstName && lastName) {
$zopim.livechat.setName(`${firstName} ${lastName}`);
}
if (email) {
$zopim.livechat.setEmail(email);
}
});
}
}, [isZopimReady]);
/**
* used to set isZopimReady to true
* once script is ready and $zopim is defined
*/
useInterval(
() => {
if (status === "ready" && typeof $zopim !== "undefined") {
setIsZopimReady(true);
}
return;
},
!isZopimReady ? 200 : null,
);
return null;
};
export default Zendesk;