React logo

React Integration

Embed the Maison concierge chat widget in a React application using a reusable component that handles script loading and cleanup via useEffect. React official site ↗

Prerequisites

  • React 16.8+ (hooks support required)
  • Your Client UUID — find it in the Business Console under Settings
  • A client-side rendering context (not SSR — see note below)

Steps

  1. Create the MaisonChat component

    Create a new file MaisonChat.tsx in your components folder. The component injects the bundle script on mount and removes it on unmount, so it is safe to use in a component tree.

    tsx
    import { useEffect } from 'react';
    
    export function MaisonChat({ clientId }: { clientId: string }) {
      useEffect(() => {
        const script = document.createElement('script');
        script.src = 'https://agent.maison-labs.com/agent-inject.bundle.js';
        script.onload = () => {
          const sessionId = new URLSearchParams(window.location.search).get('mcbsid');
          const mcbs = (window as any).initMcbs({
            clientId,
            sessionId,
            // locale: 'en-US',                     // Override browser locale
            // iconPosition: { top: 0, bottom: 20, left: 0, right: 20 },  // Chat icon position (px)
            // onSessionUpdate: (id) => console.log('Session:', id),
            // onLocaleUpdate: (locale) => console.log('Locale:', locale),
          });
          mcbs.showIcon();
        };
        document.head.appendChild(script);
    
        return() => {
          document.head.removeChild(script);
        };
      }, [clientId]);
    
      return null;
    }
  2. Render MaisonChat in your app

    Import and render the component near the root of your application. Pass your Client UUID as the clientId prop.

    tsx
    import { MaisonChat } from './MaisonChat';
    
    export default function App() {
      return(
        <>
          <MaisonChat clientId="YOUR_CLIENT_UUID" />
          {/* rest of your app */}
        </>
      );
    }
  3. Optionally wire up session callbacks

    If you need to persist or observe the session ID (for example to resume a conversation), extend the component to accept an onSessionUpdate prop.

    tsx
    import { useEffect } from 'react';
    
    export function MaisonChat({
      clientId,
      onSessionUpdate,
    }: {
      clientId: string;
      onSessionUpdate?: (sessionId: string) => void;
    }) {
      useEffect(() => {
        const script = document.createElement('script');
        script.src = 'https://agent.maison-labs.com/agent-inject.bundle.js';
        script.onload = () => {
          const sessionId = new URLSearchParams(window.location.search).get('mcbsid');
          const mcbs = (window as any).initMcbs({
            clientId,
            sessionId,
            // locale: 'en-US',                     // Override browser locale
            // iconPosition: { top: 0, bottom: 20, left: 0, right: 20 },  // Chat icon position (px)
            onSessionUpdate,
            // onLocaleUpdate: (locale) => console.log('Locale:', locale),
          });
          mcbs.showIcon();
        };
        document.head.appendChild(script);
    
        return() => {
          document.head.removeChild(script);
        };
      }, [clientId, onSessionUpdate]);
    
      return null;
    }
  4. Verify in DevTools

    Open your browser DevTools, switch to the Elements tab, and look for #maison-chat-icon in the DOM. If it's present, the widget initialised correctly.

For the full list of configuration options, control methods, and callbacks, see the Widget SDK Reference.

Common mistakes
Calling initMcbs without onload. Setting script.src and immediately calling window.initMcbs() will fail because the script has not finished loading. Always call initMcbs inside script.onload.
SSR / server-side rendering. window does not exist on the server. This component is safe because useEffect only runs in the browser. Do not import or call initMcbs at module level in any file that may be server-rendered.
Mounting the component multiple times. If MaisonChat is rendered in multiple places simultaneously, multiple script tags will be injected. Keep a single instance at the top level of your app (e.g. in App.tsx or the root layout).
Using string values for iconPosition. Write 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.