Printers
Helix Prototyping Lab · 8 printers · updated just now
Printing5/8
Queued14 jobsabout 31 h of printing
Success, last 7 days96.4%2 failed of 55
PETG, orange0.4 kgReorder soon
Helix Prototyping Lab · 8 printers · updated just now
How it works
Inside an app, a floating chat bubble gets in the way. Hide it, show your own Support entry only when someone can answer, and open the chat already knowing who is asking and what they are looking at.
This is how Stand's own dashboard offers Support (live).
data-stand-id="demo", Stand Chat's shared demo site, which works on any domain. Its demo Stand-in follows the page's greeting and prompt, but won't speak for the made-up business. With your own Site ID, your own Stand-ins answer.<script defer src="https://cdn.stand.chat/widget/stand.js" data-stand-id="YOUR-SITE-ID"></script>
<script defer src="support.js"></script>
Deferred scripts run in order, so window.StandChat exists by the time support.js runs. The first thing it does is hide Stand's floating button.
The sidebar button and any contextual button start hidden. data-support-* attributes carry what each one sends: a greeting for the user, and private context about where they are. Render them from your session and the current screen.
<button type="button" data-support hidden
data-support-greeting="Hi Maya! What can I help you with in Layerline today?"
data-support-prompt="Maya Chen, lab manager at Helix Prototyping Lab, opened Support from the sidebar on the Printers page…">
Support <span class="live"></span>
</button>
<button type="button" hidden
data-support-greeting="I see Heron paused with E-217. Let's get it printing again…"
data-support-prompt="The user is looking at printer Heron (LX-2, firmware 4.3.1)…">
Get help with E-217
</button>
const user = { id: 'usr_4821', name: 'Maya Chen' }; // From your app's session.
function connectSupport(stand) {
stand.initiallyHideChatButton();
stand.identify({ externalId: user.id, name: user.name });
stand.whenAvailable(() => {
for (const el of document.querySelectorAll('[data-support], [data-support-prompt]')) {
el.hidden = false;
}
});
document.addEventListener('click', (event) => {
const trigger = event.target.closest('[data-support], [data-support-prompt]');
if (!trigger) return;
stand.openChat(trigger.dataset.supportGreeting ?? '', {
prompt: trigger.dataset.supportPrompt ?? '',
analyticsId: trigger.dataset.supportId ?? '',
});
});
}
// stand.js is deferred and can be blocked, so wait for its API.
(function waitForStand(tries = 0) {
if (window.StandChat) return connectSupport(window.StandChat);
if (tries < 200) setTimeout(() => waitForStand(tries + 1), 50);
})();
initiallyHideChatButton() keeps Stand's own button off screen until your code opens the chat. Call it before Stand finds a responder, as support.js does right after the script loads.whenAvailable is the gate. It runs when Stand has a responder, right away if it already has one. If nobody can answer, your button stays hidden rather than opening an empty chat. The callback also gets { human, name, title, avatarUrl } if you want to show who will answer.identify is for new conversations. Call it when the signed-in user is known, and identify(null) on sign-out. Reps see the name; the ID stays private. It is page-supplied metadata, never proof of identity.openChat simply reopens it.whenAvailable returns and call it on unmount.npx degit standchat/examples/in-app-support my-app-support