So, is there an embed pattern to embed/integrate the chatbot into my reactJS SPA ? I couldn'y find an example or even an npm module for the chatbot. Is there a clean integration pattern for this into react ? Please share details.
Just wanted to post my take on it. I needed the ability to control the widget via a custom button in my app.
I created a provider for the widget and used CSS to show/hide the widget.
First and most important, is to make sure the widget won't load initally, so in the index.html you sould add this snippet at the end of the <body> tag:
<!-- Start of HubSpot Embed Code --> <script> window.hsConversationsSettings = { loadImmediately: false, inlineEmbedSelector: '#hubspot-conversations-inline-embed-selector', }; </script> <script type="text/javascript" id="hs-script-loader" async defer src="//js-na1.hs-scripts.com/your-portal-id-here.js"></script> <!-- End of HubSpot Embed Code -->
This is the provider: HubspotConversationsProvider.tsx
import { createStyles } from '@mantine/core'; import React, { createContext, FC, useCallback, useContext, useEffect, useState, } from 'react'; import ReactDOM from 'react-dom'; import { useLocation } from 'react-router-dom'; interface HubspotConversationsContextType { toggleWidget: () => void; isOpen: boolean; unreadMessagesCount: number; }
const HubspotConversationsContext = createContext<HubspotConversationsContextType | null>(null); const HUBSPOT_INLINE_EMBED_ELEMENT_ID = 'hubspot-conversations-inline-embed-selector'; export const HubspotConversationsProvider: FC = ({ children }) => { const location = useLocation(); const [isReady, setIsReady] = useState(false); const [isOpen, setIsOpen] = useState(false); const [unreadMessagesCount, setUnreadMessagesCount] = useState(0); const { classes } = useStyles(isOpen); const user = useCurrentUser(); // This is for Visitor Identification API const hubspotToken = useHubspotConversationsToken(); const hideWidget = useCallback(() => { setIsOpen(false); }, []); const showWidget = useCallback(() => { if (!isReady) return; window.HubSpotConversations.widget.load(); window.HubSpotConversations.widget.open(); setIsOpen(true); }, [isReady]); const toggleWidget = useCallback(() => { if (isOpen) { hideWidget(); } else { showWidget(); } }, [hideWidget, isOpen, showWidget]); const onConversationsReady = useCallback(() => { setIsReady(true); }, []); useEffect( function init() { if (window.HubSpotConversations) { onConversationsReady(); } else { window.hsConversationsOnReady = [onConversationsReady]; } }, [onConversationsReady] ); useEffect( function updateSettingsAndLoadWidget() { if (hubspotToken.isFetched && hubspotToken?.data) { window.hsConversationsSettings = { ...window.hsConversationsSettings, identificationEmail: user?.email, identificationToken: hubspotToken.data.token, }; window.HubSpotConversations.widget.load(); } }, [hubspotToken.data, hubspotToken.isFetched, user?.email] ); useEffect( function addEventListeners() { if (!isReady) return; function listener(payload: { unreadCount: number }) { setUnreadMessagesCount(payload.unreadCount); }
It should work, but it may depend on how you're handling routing. Basically the way the chat function works is you add the standard HS scripts and then configure (in HubSpot) where and when the live chat should pop up. Basically the script needs to be available for the whole app, and then the triggers are handled on HubSpot's side instead of in your codebase. I'm not aware of an NPM or webpack-friendly method of bundling that script, however. I've always done it manually.
There may be a conflict between React versions since HubSpot uses React for a lot of their on-page tools. That shouldn't happen, but it is something I've run into in the past. React Dev Tools might help diagnose if there's something like that going on.
I guess if you're using React Router - or some other router you can simply invoke window.HubSpotConversations.widget.refresh(); which apparently re-runs the page matching logic based on the current URL.
I haven't done this myself but I've been doing some searching around our forums. Here's an example from a while back where someone added the tracking code to a React app: https://community.hubspot.com/t5/APIs-Integrations/Tracking-code-for-a-single-page-application-made-.... If you look at the bottom response there, the user built a page listener component. Maybe that would help with what you're trying to do?
1. Add the script in "index.html" 2. Append the script to the "body" element in a "useEffect" Hook defined in the top-level "App" component
None worked (with React 16.11.0). Unfortunately, this is a showstopper, forcing me to go find another live chat product.
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="https://js.hs-scripts.com/MY_ID.js" async></script>
</body>