Add the Maison concierge chat widget to any static HTML page in two steps — no build tools or frameworks required. Plain HTML official site ↗
Prerequisites
- Access to edit your HTML files
- Your Client UUID — find it in the Business Console under Settings
- The page must be served over HTTP/HTTPS (not opened directly as a file)
Steps
Add the script tag to <head>
Paste the following line inside your
<head>element. It loads the widget bundle from Maison's CDN.html<script src="https://agent.maison-labs.com/agent-inject.bundle.js" data-cfasync="false" data-no-minify="1" data-no-optimize="1" data-no-defer="1" data-noptimize="1"></script>Add the init script before </body>
Paste this script block just before your closing
</body>tag. ReplaceYOUR_CLIENT_UUIDwith the UUID from your Business Console.html<script> document.addEventListener('DOMContentLoaded', function() { function getQueryParam(param) { var queryString = window.location.search; var urlParams = new URLSearchParams(queryString); return urlParams.get(param); } var sessionId = getQueryParam('mcbsid'); var mcbs = window.initMcbs({ clientId: 'YOUR_CLIENT_UUID', sessionId: sessionId, // locale: 'en-US', // Override browser locale // iconPosition: { top: 0, bottom: 20, left: 0, right: 20 }, // Chat icon position (px) // loadChatWindow: 'load', // When the chat window loads: 'load' (default), 'interaction', 'lazy' or 'eager' // onSessionUpdate: function(id) { console.log('Session:', id); }, // onLocaleUpdate: function(locale) { console.log('Locale:', locale); }, }); mcbs.showIcon(); }); </script>Save and open your page in a browser
Load or reload your page. Within a few seconds you should see the Maison chat icon appear in the bottom-right corner.
Verify in DevTools
Open your browser DevTools, switch to the Elements tab, and look for
#maison-chat-iconin the DOM. If it's present, the widget initialised correctly.
Full page example
A complete minimal HTML page with both snippets in their correct positions.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>My Hotel</title>
<!-- Maison chat widget -->
<script src="https://agent.maison-labs.com/agent-inject.bundle.js" data-cfasync="false" data-no-minify="1" data-no-optimize="1" data-no-defer="1" data-noptimize="1"></script>
</head>
<body>
<h1>Welcome to our hotel</h1>
<!-- Maison chat init — placed at end of body -->
<script>
document.addEventListener('DOMContentLoaded', function() {
function getQueryParam(param) {
var queryString = window.location.search;
var urlParams = new URLSearchParams(queryString);
return urlParams.get(param);
}
var sessionId = getQueryParam('mcbsid');
var mcbs = window.initMcbs({
clientId: 'YOUR_CLIENT_UUID',
sessionId: sessionId,
// locale: 'en-US', // Override browser locale
// iconPosition: { top: 0, bottom: 20, left: 0, right: 20 }, // Chat icon position (px)
// loadChatWindow: 'load', // When the chat window loads: 'load' (default), 'interaction', 'lazy' or 'eager'
// onSessionUpdate: function(id) { console.log('Session:', id); },
// onLocaleUpdate: function(locale) { console.log('Locale:', locale); },
});
mcbs.showIcon();
});
</script>
</body>
</html>For the full list of configuration options, control methods, and callbacks, see the Widget SDK Reference.
Common mistakes
<head> before the agent-inject.bundle.js script tag, window.initMcbs will be undefined. Always place the init script after the bundle tag, or use DOMContentLoaded.initMcbs at the top of a bare <script> tag that loads synchronously, it may run before the DOM is ready. Wrapping in DOMContentLoaded is the safest pattern.defer to the bundle script tag delays execution until after parsing. The DOMContentLoaded listener pattern above handles this correctly — do not remove it if you add defer.bottom: 20, not bottom: '20px'. Values are plain numbers representing pixels — do not include units.Not sure if it's set up correctly? Use the Site Diagnostic tool.