Live Chat Causing CLS Issues

RAdams6
Participant

Hello,

 

As per title, the live chat loading and even the delayed prompt is causing my website to upset Google and cause CLS issues.

 

I have tried:

 

- Delaying the live chat prompt for 7 seconds

- Turning off the live chat prompt

 

But I am still getting issues:

 

Screenshot 2021-03-23 at 12.35.28.png

 

Screenshot 2021-03-23 at 12.34.35.png

 

How can I fix this issue?

 

Thanks

1 Accepted solution
MichaelMaguire
Solution
Participant

As of October 2024 the chat widget still appears to be negativley affecting CLS.

 

On the Chrome's dev tools I recorded what happens when the chat is loaded onto the page using a slow connection and a throttled CPU. It looks as though an unidentifiable HTML node associated with the chat jumps from the top of the page down to the bottom, this is what I believe causes the CLS score to spike, even though nothing on the page appears to be impacted by this:

 

Unidentified node causing CLS spikeUnidentified node causing CLS spike

 

So I took this approach to fix the issue:

 

1. Added a placeholder HTML node to the page that looks like the chat icon. Below is the HTML and CSS used.

 

HTML

 

 

<div id="esChatPlaceholder" class="es-chat-placeholder"></div>

 

 

 

 

CSS

 

 

.es-chat-placeholder {
    background:    #d9342b url("data&colon;image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' fill-rule='evenodd' viewBox='0 0 32 30'%3E%3Cpath d='M30.7 3.5Q30.25 1.1 28 .8S24.2.1 18.4.1 8.8.8 8.8.8c-1.2.2-2 .8-2.5 1.8 2.5-.3 5-.4 7.6-.4 5.7 0 9.4.7 10 .8 2.5.4 4.2 2.1 4.7 4.6.2.8.8 3.7.8 7.2s-.2 3.6-.3 4.9c1-.4 1.6-1.3 1.8-2.5 0 0 .7-3.1.7-6.8s-.7-6.8-.7-6.8m-4.7 4.3q-.45-2.4-2.7-2.7s-3.8-.7-9.6-.7-9.6.7-9.6.7c-1.5.2-2.5 1.2-2.7 2.7 0 0-.7 3.1-.7 6.8s.7 6.8.7 6.8q.45 2.4 2.7 2.7s2.4.5 6.4.6l2.4 4.1c.3.4.8.6 1.3.3.1 0 .3-.2.3-.3l2.4-4.1 6.4-.6C25 24 26 23 26.2 21.5c0 0 .7-3.1.7-6.8s-.7-6.8-.7-6.8'/%3E%3C/svg%3E") 50%/32px 32px no-repeat;
    border-radius: 100%;
    bottom:        15px;
    box-shadow:    rgba(0, 0, 0, 0.1) 0px 1px 4px, rgba(0, 0, 0, 0.2) 0px 2px 12px;
    height:        62px;
    left:          15px;
    position:      fixed;
    width:         62px;
    z-index:       9000;
}


@media (pointer: coarse) {
    .es-chat-placeholder {
        bottom: 7px;
        left:   7px;
    }
}

 

 

 

 

2. Because the CLS issue was only happening on mobile devices, I used the below JavaScript functionality to load the chat functionality differently, depending on whether or not the user is on a mobile or desktop device.

For all devices: The URL fragment "'#show-chat" is added to the URL and then the chat is loaded. You will need to configure your chat inbox settings to look for the "#show-chat" URL fragment before calling the chat load functionality:

Wildcard matchWildcard match
Doing the above will stop the chat from loading until "#show-chat" is added to the URL.

 

For desktop devices: Scrolling, moving the mouse, or clicking, causes the chat to be loaded onto the page.

For mobile devices: The placeholder itself has to be clicked before the chat is loaded onto the page.

 

Below is the JavaScript I used:

 

 

(function(win, doc)
{
    'use strict';

    var loadChatCounter = 0,
    isTouchDevice = function()
    {
        return ('ontouchstart' in win) || (win.navigator.maxTouchPoints > 0) || (win.navigator.msMaxTouchPoints > 0);
    },
    loadChatWidget = function()
    {
        var urlFragment     = '#show-chat',
        locationHref        = win.location.href,
        containsURLfragment = locationHref.indexOf(urlFragment);

        if (typeof win.HubSpotConversations === 'undefined' || (containsURLfragment !== -1 && loadChatCounter === 0)) {
            return;
        }

        var mobileDevice = isTouchDevice() === true && (win.innerWidth < 768),
        placeHolder      = doc.getElementById('esChatPlaceholder'),

        loadHSChat = function()
        {
            var status = win.HubSpotConversations.widget.status();

            if (status.pending || status.loaded) {
                return;
            }

            if (containsURLfragment === -1) {
                win.history.replaceState(null, doc.title, locationHref + urlFragment);
            }

            if (loadChatCounter === 0) {
                win.HubSpotConversations.widget.load();
                loadChatCounter++;

                if (mobileDevice === true && placeHolder !== null) {
                    win.HubSpotConversations.widget.open();
                    placeHolder.removeEventListener('click', loadHSChat, false);
                }

                if (placeHolder !== null) {
                    placeHolder.parentNode.removeChild(placeHolder);
                }
            }
        };

        if (mobileDevice === true && placeHolder !== null) {
            placeHolder.addEventListener('click', loadHSChat, false);
        }

        if (mobileDevice === false) {
            loadHSChat();
        }
    },

    eventListener = function()
    {
        if (loadChatCounter === 0) {
            loadChatWidget();
        } else if (loadChatCounter > 0) {
            // Removed event listeners after the chat widget loaded
            doc.removeEventListener('click', eventListener, false);
            win.removeEventListener('mousemove', eventListener, false);
            win.removeEventListener('scroll', eventListener, false);
        }
    };

    // Bind the initialisation of the chat to whatever event listeners you want, I chose these 3:
    doc.addEventListener('click', eventListener, false);
    win.addEventListener('mousemove', eventListener, false);
    win.addEventListener('scroll', eventListener, false);
})(
    window,
    window.document
);

 

 

 

Implementing this improved our CLS score within a few days (it was 0.15, on average, prior to taking this screenshot):


CLS average improvementCLS average improvement

 

The long and short of it, uers on mobile devices will not be exposed to the CLS conditions unless they actually want to load the chat (by clicking the placeholder). I Hope this helps somebody!


I should add that loading the chat within a custom HTML node via the "inlineEmbedSelector" JavaScript property could make a difference as localising the associated layout shift to a descendent node, which you can style, could have a positive impact on your website's CLS score:

 

 

(function(win)
{
    window.hsConversationsSettings = {
        loadImmediately: false,
        inlineEmbedSelector: '#some-id',
        enableWidgetCookieBanner: true,
        disableAttachment: true
    };
})(window);

 

 

 

View solution in original post

20 Replies 20
IMakkar
Member

Hi @RAdams6 ,

I understand how concerning this can be—CLS (Cumulative Layout Shift) caused by the live chat widget is a common issue, especially with dynamic elements like iframes. However, there are effective solutions to address this and improve your site's standing with Google.

Here’s a step-by-step guide to fixing the CLS issue:

 

Reserve Space for the Chat Widget The most effective way to prevent layout shifts is to allocate a fixed area for the chat widget to load into. Add CSS to ensure the iframe has predefined dimensions, like so:

 .hubspot-messages-iframe-container {
    width: 276px; /* Match the iframe dimensions */
    height: 222px; /* Match the iframe dimensions */
    position: fixed;
    bottom: 0;
    right: 0;
}

This ensures the space is reserved before the widget loads, eliminating shifts.

 

Preload Fonts and Styles Sometimes, the text or styling inside the chat widget can also cause shifts. Preload the necessary fonts and styles:

<link rel="preload" href="widget-font-url.woff2" as="font" type="font/woff2" crossorigin="anonymous">

This ensures the content inside the widget loads smoothly.

 

Adjust Chat Loading Behavior

  • Delay Chat Initialization: If you’ve already tried delaying the prompt, extend it further (e.g., 10 seconds) and test if it reduces CLS.
  • Lazy Loading: Enable lazy loading for the chat widget so it only initializes after the rest of the page is fully loaded.

Reduce Chat Widget Dependencies Turn off features you don’t need, such as animations or unnecessary prompts, as they can contribute to CLS. This can usually be managed in HubSpot’s chat settings.

 

Alternate, If you’re looking for a faster, automated fix, I recommend trying Website Speedy, a speed optimization app specifically designed for HubSpot websites.

The app takes only 5 minutes to set up, and you can enjoy a 14-day free trial to see how it impacts your site’s performance.


Install Website Speedy here: https://ecosystem.hubspot.com/marketplace/apps/website-speedy

(Disclaimer: We are the developers of this tool and are happy to answer any questions!)

0 Upvotes
MichaelMaguire
Solution
Participant

As of October 2024 the chat widget still appears to be negativley affecting CLS.

 

On the Chrome's dev tools I recorded what happens when the chat is loaded onto the page using a slow connection and a throttled CPU. It looks as though an unidentifiable HTML node associated with the chat jumps from the top of the page down to the bottom, this is what I believe causes the CLS score to spike, even though nothing on the page appears to be impacted by this:

 

Unidentified node causing CLS spikeUnidentified node causing CLS spike

 

So I took this approach to fix the issue:

 

1. Added a placeholder HTML node to the page that looks like the chat icon. Below is the HTML and CSS used.

 

HTML

 

 

<div id="esChatPlaceholder" class="es-chat-placeholder"></div>

 

 

 

 

CSS

 

 

.es-chat-placeholder {
    background:    #d9342b url("data&colon;image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' fill-rule='evenodd' viewBox='0 0 32 30'%3E%3Cpath d='M30.7 3.5Q30.25 1.1 28 .8S24.2.1 18.4.1 8.8.8 8.8.8c-1.2.2-2 .8-2.5 1.8 2.5-.3 5-.4 7.6-.4 5.7 0 9.4.7 10 .8 2.5.4 4.2 2.1 4.7 4.6.2.8.8 3.7.8 7.2s-.2 3.6-.3 4.9c1-.4 1.6-1.3 1.8-2.5 0 0 .7-3.1.7-6.8s-.7-6.8-.7-6.8m-4.7 4.3q-.45-2.4-2.7-2.7s-3.8-.7-9.6-.7-9.6.7-9.6.7c-1.5.2-2.5 1.2-2.7 2.7 0 0-.7 3.1-.7 6.8s.7 6.8.7 6.8q.45 2.4 2.7 2.7s2.4.5 6.4.6l2.4 4.1c.3.4.8.6 1.3.3.1 0 .3-.2.3-.3l2.4-4.1 6.4-.6C25 24 26 23 26.2 21.5c0 0 .7-3.1.7-6.8s-.7-6.8-.7-6.8'/%3E%3C/svg%3E") 50%/32px 32px no-repeat;
    border-radius: 100%;
    bottom:        15px;
    box-shadow:    rgba(0, 0, 0, 0.1) 0px 1px 4px, rgba(0, 0, 0, 0.2) 0px 2px 12px;
    height:        62px;
    left:          15px;
    position:      fixed;
    width:         62px;
    z-index:       9000;
}


@media (pointer: coarse) {
    .es-chat-placeholder {
        bottom: 7px;
        left:   7px;
    }
}

 

 

 

 

2. Because the CLS issue was only happening on mobile devices, I used the below JavaScript functionality to load the chat functionality differently, depending on whether or not the user is on a mobile or desktop device.

For all devices: The URL fragment "'#show-chat" is added to the URL and then the chat is loaded. You will need to configure your chat inbox settings to look for the "#show-chat" URL fragment before calling the chat load functionality:

Wildcard matchWildcard match
Doing the above will stop the chat from loading until "#show-chat" is added to the URL.

 

For desktop devices: Scrolling, moving the mouse, or clicking, causes the chat to be loaded onto the page.

For mobile devices: The placeholder itself has to be clicked before the chat is loaded onto the page.

 

Below is the JavaScript I used:

 

 

(function(win, doc)
{
    'use strict';

    var loadChatCounter = 0,
    isTouchDevice = function()
    {
        return ('ontouchstart' in win) || (win.navigator.maxTouchPoints > 0) || (win.navigator.msMaxTouchPoints > 0);
    },
    loadChatWidget = function()
    {
        var urlFragment     = '#show-chat',
        locationHref        = win.location.href,
        containsURLfragment = locationHref.indexOf(urlFragment);

        if (typeof win.HubSpotConversations === 'undefined' || (containsURLfragment !== -1 && loadChatCounter === 0)) {
            return;
        }

        var mobileDevice = isTouchDevice() === true && (win.innerWidth < 768),
        placeHolder      = doc.getElementById('esChatPlaceholder'),

        loadHSChat = function()
        {
            var status = win.HubSpotConversations.widget.status();

            if (status.pending || status.loaded) {
                return;
            }

            if (containsURLfragment === -1) {
                win.history.replaceState(null, doc.title, locationHref + urlFragment);
            }

            if (loadChatCounter === 0) {
                win.HubSpotConversations.widget.load();
                loadChatCounter++;

                if (mobileDevice === true && placeHolder !== null) {
                    win.HubSpotConversations.widget.open();
                    placeHolder.removeEventListener('click', loadHSChat, false);
                }

                if (placeHolder !== null) {
                    placeHolder.parentNode.removeChild(placeHolder);
                }
            }
        };

        if (mobileDevice === true && placeHolder !== null) {
            placeHolder.addEventListener('click', loadHSChat, false);
        }

        if (mobileDevice === false) {
            loadHSChat();
        }
    },

    eventListener = function()
    {
        if (loadChatCounter === 0) {
            loadChatWidget();
        } else if (loadChatCounter > 0) {
            // Removed event listeners after the chat widget loaded
            doc.removeEventListener('click', eventListener, false);
            win.removeEventListener('mousemove', eventListener, false);
            win.removeEventListener('scroll', eventListener, false);
        }
    };

    // Bind the initialisation of the chat to whatever event listeners you want, I chose these 3:
    doc.addEventListener('click', eventListener, false);
    win.addEventListener('mousemove', eventListener, false);
    win.addEventListener('scroll', eventListener, false);
})(
    window,
    window.document
);

 

 

 

Implementing this improved our CLS score within a few days (it was 0.15, on average, prior to taking this screenshot):


CLS average improvementCLS average improvement

 

The long and short of it, uers on mobile devices will not be exposed to the CLS conditions unless they actually want to load the chat (by clicking the placeholder). I Hope this helps somebody!


I should add that loading the chat within a custom HTML node via the "inlineEmbedSelector" JavaScript property could make a difference as localising the associated layout shift to a descendent node, which you can style, could have a positive impact on your website's CLS score:

 

 

(function(win)
{
    window.hsConversationsSettings = {
        loadImmediately: false,
        inlineEmbedSelector: '#some-id',
        enableWidgetCookieBanner: true,
        disableAttachment: true
    };
})(window);

 

 

 

SEsposito4
Participant

If we have the chat bot on almost every page would this have to be done manually on each page or would there be a way to make this mobile placeholder universal across all pages?

0 Upvotes
MichaelMaguire
Participant

The CSS and JavaScript would, ideally, go into your website's global stylesheet and JavaScript, respectively, to be referenced on every page. The HTML snippet would go into the website's global footer.

 

This method disables the chat widget initially and only enables it based on the event listeners: "click", "mousemove", and "scroll".

0 Upvotes
EXWE-GmbH
Member

A possible solution would be the ability to load the chat inside a specific DOM Element.

We tried a solution using this implementation we found in the docs:
<script>
window.hsConversationsSettings = {
loadImmediately: true,
inlineEmbedSelector: '#hubspot-messages-iframe-container',
enableWidgetCookieBanner: false,
disableAttachment: true
};
window.hsConversationsOnReady = [
() => {
window.HubSpotConversations.widget.load({ widgetOpen: false });
},
];
</script>


The problem here is, that there is a parameter "widgetOpen: false" but this one doesnt work as expected.
If its true, the widget is directly open. If its false, there is no mobile /open button.

 

But we think this is a good start. Any ideas on this?

Best regards, EXWE Dortmund, Germany

0 Upvotes
hakancanada
Contributor

Hey there,

I went through the thread and it seems that issue hasn't been fixed yet because we also experience CLS issue on our end. Any possible solution if you are able to fix this issue. 

 

Thanks.

@RAdams6 @CTimothyBedna 

0 Upvotes
acgorecki
Participant

Since Cumulative Layout Shift (CLS) is a Core Web Vital and Core Web Vitals are now part of the Google ranking algorithm, this should be addressed by Hubspot. Below is a screenshot that is showing that the Hubspot live chat widget is the only thing causing my site to have CLS issues and I am considering removing it. The Live Chat widget is also affecting my Largest Contentful Paint (LCP).

acgorecki_0-1642815529452.png

 

0 Upvotes
gusdev
Participant

Any updates on this CLS issue? Also running into the same problems for our site.

0 Upvotes
CTimothyBedna
Member

I recently added Hubspot Chat to my web app that actually helps people fix Core Web Vitals. And I was a bit shocked that out of the box that the Hubspot chat triggered massive CLS numbers (my site went from 0 to 0.407 which is 4x over what Google considers acceptable). I "fixed" the issue by adding inline CSS to the <head> of my page that assigned a height and width to the Chat component. This mitigated the issue. Basically, the problem is caused because the iframe inserted by the chat script does not have height and width attributes, so it resizes once the script executes and adds a height and width inline. In order for this "hack" to work for you, you need to open DevTools > Inspect > Select the chat component (#hubspot-messages-iframe-container) and check out what the height and width are -- then use those in your CSS. Now in my case, I leave Chat as always available so the height and width are predictable.

 

#hubspot-messages-iframe-container{
width: 276px;
height: 270px;
}

 

Here is a link to my tool, which is measuring my tool (kinda weird). If you continue to have issues, just hit me up via Chat and I'll get back to you. Another way to fix this would be to inline all the chat CSS or load the chat script after window.load (but that might not fix it as CLS is cumulative so it measures shifts no matter when they occur).

 

https://waterfaller.dev/?url=https://waterfaller.dev/

CTimothyBedna
Member

Nope, that solution does not seem to work either. If I find a way to fix this, I will post it. If you do not see any more here, then my solution was to find another vendor.

02606
Member

Exactly the same issue here. The chatbot has seriously impacted our CLS scoring. Such a pivotal part of hubspot needs repairing.

0 Upvotes
donrua
Guide

Same here. I can view frame by frame with Chrome inspector, and in mobile and appears as the chatbot gets involved ,the CLS begins. It's also a detriment to TTFB I believe, the loading/processing of chatbot script. Needs attention.

0 Upvotes
NReijmerink
Participant

Very much like to see a fix to this as well. The chat function causes a CLS that is far above acceptable for CWV.

 

 

RAdams6
Participant

Nice to see I'm not the only one @NReijmerink 

 

@sharonlicari Can you or anyone from Hubspot comment?

 

I know the suggestion is to ensure there is a 5 second or more delay for the chat launcher, but this clearly isn't a fix for CLS issues.

RAdams6
Participant

I have found the cause of the CLS issue...

 

It's the chat launcher.

 

Even if you include a delay of 8 seconds, there seems to be a div that move across the viewport as the chat launcher loads.

 

Unfortunate as we liked this feature, but turning it off has reduced our CLS issues massively.

 

Anyone from Hubspot care to comment? Core Web Vitals come into play in just a month's time!

sharonlicari
HubSpot Alumni
HubSpot Alumni

Hey @RAdams6 

 

Thank you for reaching out!

 

I think this thread can guide on this. 

 

I hope this helps

 

Thanks

Sharon

 


loop Loop Marketing is a new four-stage approach that combines AI efficiency and human authenticity to drive growth.
Learn More

0 Upvotes
RAdams6
Participant

Hi @sharonlicari 

 

Many thanks for your reply.

 

Unfortunately that thread doesn't seem to allude to much...

 

The answers seem to be talking about the CMS, I am not using the CMS, only the live chat.

 

Thanks

CPriebe
Participant

Somehow this seems to be how every Hubspot support request seems to end. By a HS rep posting some random thread and then abandonding the customer.

DianaGomez
Community Manager
Community Manager

Hi  @CPriebe hope you are doing well!

 

Since this is an old thread, I encourage you to create a new conversation, this way more users will be able to see it. Please make sure to add context, screenshots, and all the details you can.

 

Best,
Diana


loop Loop Marketing is a new four-stage approach that combines AI efficiency and human authenticity to drive growth.
Learn More

0 Upvotes
JdeBoisblanc
Participant

The more recent thread links here... interestingly by Hubspot support...

I think I had success with Timothy's trick. In CSS (on my Wordpress site) I set the iframe size (after inspecting it to determine its rendered size):

#hubspot-messages-iframe-container {
width: 100px;
height: 120px;
}

 

0 Upvotes