Skip to content

Instantly share code, notes, and snippets.

@steve8708
Created November 12, 2021 17:46
Show Gist options
  • Save steve8708/1a785503bf33c01728130cfa9a594ab8 to your computer and use it in GitHub Desktop.
Save steve8708/1a785503bf33c01728130cfa9a594ab8 to your computer and use it in GitHub Desktop.
Intercom Facade - render a placeholder of the intercom button that doesn't load the heavy widget JS until clicked. Boosted our lighthouse score ~15 points
const INTERCOM_KEY = /* YOUR KEY HERE */;
export function IntercomFacade() {
return (
<div className="intercom-lightweight-app" aria-live="polite">
<style>{INTERCOM_STYLE}</style>
<div
className="intercom-lightweight-app-launcher intercom-launcher"
role="button"
tabIndex={0}
arial-label="Open Intercom Messenger"
onClick={(e) => bootIntercom(e.target as HTMLElement)}
>
<div className="intercom-lightweight-app-launcher-icon intercom-lightweight-app-launcher-icon-open">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 32">
<path d="M28 32s-4.714-1.855-8.527-3.34H3.437C1.54 28.66 0 27.026 0 25.013V3.644C0 1.633 1.54 0 3.437 0h21.125c1.898 0 3.437 1.632 3.437 3.645v18.404H28V32zm-4.139-11.982a.88.88 0 00-1.292-.105c-.03.026-3.015 2.681-8.57 2.681-5.486 0-8.517-2.636-8.571-2.684a.88.88 0 00-1.29.107 1.01 1.01 0 00-.219.708.992.992 0 00.318.664c.142.128 3.537 3.15 9.762 3.15 6.226 0 9.621-3.022 9.763-3.15a.992.992 0 00.317-.664 1.01 1.01 0 00-.218-.707z"></path>
</svg>
</div>
<div className="intercom-lightweight-app-launcher-icon intercom-lightweight-app-launcher-icon-minimize">
<svg viewBox="0 0 16 14" xmlns="http://www.w3.org/2000/svg">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M.116 4.884l1.768-1.768L8 9.232l6.116-6.116 1.768 1.768L8 12.768.116 4.884z"
></path>
</svg>
</div>
</div>
<style id="intercom-lightweight-app-style" type="text/css">
{INTERCOM_STYLE}
</style>
</div>
);
}
function loadScript(url: string) {
return new Promise<void>((resolve) => {
const script = document.createElement('script');
script.addEventListener('load', () => {
resolve();
});
script.src = url;
document.body.appendChild(script);
});
}
async function bootIntercom(element: HTMLElement) {
await loadScript(`https://widget.intercom.io/widget/${INTERCOM_KEY}`);
const container = element.parentElement!;
const body = container.parentElement!;
body.removeChild(container);
const { Intercom } = window as any;
Intercom('boot', { app_id: INTERCOM_KEY });
Intercom('show');
}
export const INTERCOM_STYLE = `@keyframes intercom-lightweight-app-launcher {
from {
opacity: 0;
transform: scale(0.5);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes intercom-lightweight-app-gradient {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes intercom-lightweight-app-messenger {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.intercom-lightweight-app {
position: fixed;
z-index: 2147483001;
width: 0;
height: 0;
font-family: intercom-font, "Helvetica Neue", "Apple Color Emoji", Helvetica, Arial, sans-serif;
}
.intercom-lightweight-app-gradient {
position: fixed;
z-index: 2147483002;
width: 500px;
height: 500px;
bottom: 0;
right: 0;
pointer-events: none;
background: radial-gradient(
ellipse at bottom right,
rgba(29, 39, 54, 0.16) 0%,
rgba(29, 39, 54, 0) 72%);
animation: intercom-lightweight-app-gradient 200ms ease-out;
}
.intercom-lightweight-app-launcher {
position: fixed;
z-index: 2147483003;
bottom: 20px;
right: 20px;
width: 60px;
height: 60px;
border-radius: 50%;
background: #0fa6dc;
cursor: pointer;
box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.06), 0 2px 32px 0 rgba(0, 0, 0, 0.16);
animation: intercom-lightweight-app-launcher 250ms ease;
}
.intercom-lightweight-app-launcher:focus {
outline: none;
}
.intercom-lightweight-app-launcher-icon {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 60px;
height: 60px;
transition: transform 100ms linear, opacity 80ms linear;
}
.intercom-lightweight-app-launcher-icon-open {
opacity: 1;
transform: rotate(0deg) scale(1);
}
.intercom-lightweight-app-launcher-icon-open svg {
width: 28px;
height: 32px;
}
.intercom-lightweight-app-launcher-icon-open svg path {
fill: rgb(255, 255, 255);
}
.intercom-lightweight-app-launcher-icon-self-serve {
opacity: 1;
transform: rotate(0deg) scale(1);
}
.intercom-lightweight-app-launcher-icon-self-serve svg {
height: 56px;
}
.intercom-lightweight-app-launcher-icon-self-serve svg path {
fill: rgb(255, 255, 255);
}
.intercom-lightweight-app-launcher-custom-icon-open {
max-height: 36px;
max-width: 36px;
opacity: 1;
transform: rotate(0deg) scale(1);
}
.intercom-lightweight-app-launcher-icon-minimize {
opacity: 0;
transform: rotate(-60deg) scale(0);
}
.intercom-lightweight-app-launcher-icon-minimize svg {
width: 16px;
}
.intercom-lightweight-app-launcher-icon-minimize svg path {
fill: rgb(255, 255, 255);
}
.intercom-lightweight-app-messenger {
position: fixed;
z-index: 2147483003;
overflow: hidden;
background-color: white;
animation: intercom-lightweight-app-messenger 250ms ease-out;
width: 376px;
height: calc(100% - 120px);
max-height: 704px;
min-height: 250px;
right: 20px;
bottom: 100px;
box-shadow: 0 5px 40px rgba(0,0,0,0.16);
border-radius: 8px;
}
.intercom-lightweight-app-messenger-header {
height: 75px;
background: linear-gradient(
135deg,
rgb(15, 166, 220) 0%,
rgb(8, 94, 124) 100%
);
}
@media print {
.intercom-lightweight-app {
display: none;
}
}`;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment