Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: widget does not load when navigating on pages with view transition [CW-3249] #9443

Merged
merged 8 commits into from
May 15, 2024
25 changes: 24 additions & 1 deletion app/javascript/packs/sdk.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,37 @@ import {
getUserCookieName,
hasUserKeys,
} from '../sdk/cookieHelpers';
import { addClasses, removeClasses } from '../sdk/DOMHelpers';
import {
addClasses,
removeClasses,
restoreWidgetInDOM,
} from '../sdk/DOMHelpers';
import { setCookieWithDomain } from '../sdk/cookieHelpers';
import { SDK_SET_BUBBLE_VISIBILITY } from 'shared/constants/sharedFrameEvents';

const runSDK = ({ baseUrl, websiteToken }) => {
if (window.$chatwoot) {
return;
}

if (window.Turbo) {
// if this is a Rails Turbo app
document.addEventListener('turbo:before-render', event =>
restoreWidgetInDOM(event.detail.newBody)
);
}

if (window.Turbolinks) {
document.addEventListener('turbolinks:before-render', event => {
restoreWidgetInDOM(event.data.newBody);
});
}

// if this is an astro app
document.addEventListener('astro:before-swap', event =>
restoreWidgetInDOM(event.newDocument.body)
);

const chatwootSettings = window.chatwootSettings || {};
let locale = chatwootSettings.locale;
let baseDomain = chatwootSettings.baseDomain;
Expand Down
19 changes: 19 additions & 0 deletions app/javascript/sdk/DOMHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,28 @@ import { IFrameHelper } from './IFrameHelper';
export const loadCSS = () => {
const css = document.createElement('style');
css.innerHTML = `${SDK_CSS}`;
css.id = 'cw-widget-styles';
document.body.appendChild(css);
};

// This is a method specific to Turbo
// The body replacing strategy removes Chatwoot styles
// as well as the widget, this help us get it back
export const restoreElement = (id, newBody) => {
const element = document.getElementById(id);
const newElement = newBody.querySelector(`#${id}`);

if (element && !newElement) {
newBody.appendChild(element);
}
};

export const restoreWidgetInDOM = newBody => {
restoreElement('cw-bubble-holder', newBody);
restoreElement('cw-widget-holder', newBody);
restoreElement('cw-widget-styles', newBody);
};

export const addClasses = (elm, classes) => {
elm.classList.add(...classes.split(' '));
};
Expand Down
1 change: 1 addition & 0 deletions app/javascript/sdk/IFrameHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export const IFrameHelper = {
}

addClasses(widgetHolder, holderClassName);
widgetHolder.id = 'cw-widget-holder';
widgetHolder.appendChild(iframe);
body.appendChild(widgetHolder);
IFrameHelper.initPostMessageCommunication();
Expand Down
1 change: 1 addition & 0 deletions app/javascript/sdk/bubbleHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export const createBubbleHolder = hideMessageBubble => {
addClasses(bubbleHolder, 'woot-hidden');
}
addClasses(bubbleHolder, 'woot--bubble-holder');
bubbleHolder.id = 'cw-bubble-holder';
body.appendChild(bubbleHolder);
};

Expand Down