For more dynamic control, clients can use JavaScript:
<script>
// Create and inject the chatbox
(function() {
const iframe = document.createElement('iframe');
iframe.id = 'reva-chat-widget';
iframe.loading = 'eager'; // fixed-position widget, not a lazy-load candidate
// Keep allow-same-origin: the current widget needs same-origin API and WebSocket access.
// Set the sandbox before appending the iframe so it applies to the initial load.
iframe.sandbox = 'allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox';
iframe.referrerPolicy = 'no-referrer';
iframe.hidden = true; // revealed onload, or replaced by the fallback below
iframe.src = '';
iframe.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
width: 400px;
height: 600px;
border: none;
border-radius: 12px;
z-index: 999999;
`;
iframe.setAttribute('title', 'ReVa Chat');
// Visible fallback if the widget doesn't load in time โ never leave visitors
// looking at a permanently blank box
const fallback = document.createElement('a');
fallback.href = iframe.src;
fallback.target = '_blank';
fallback.rel = 'noopener noreferrer';
fallback.textContent = 'Chat';
fallback.hidden = true;
// No display here โ an inline style always beats the UA [hidden] rule, so a
// permanent display:flex would keep this visible even while hidden===true.
fallback.style.cssText = iframe.style.cssText +
'align-items:center;justify-content:center;background:#2196F3;color:#fff;text-decoration:none;';