Angular logo

Angular Integration

Embed the Maison concierge chat widget in an Angular application using a standalone component. ngOnInit handles script injection and ngOnDestroy handles cleanup. Angular official site ↗

Prerequisites

  • Angular 14+ (standalone components supported)
  • Your Client UUID — find it in the Business Console under Settings
  • Browser rendering target (not SSR — see note below)

Steps

  1. Create the MaisonChatComponent

    Create src/app/maison-chat.component.ts. The component is standalone, renders no template, and manages the script tag via the Angular lifecycle.

    typescript
    // maison-chat.component.ts
    import {
      Component,
      Input,
      OnInit,
      OnDestroy,
      OnChanges,
      SimpleChanges,
    } from '@angular/core';
    
    @Component({
      selector: 'app-maison-chat',
      standalone: true,
      template: '',  // renders nothing — manages script lifecycle only
    })
    export class MaisonChatComponent implements OnInit, OnDestroy, OnChanges {
      @Input({ required: true }) clientId!: string;
    
      private scriptEl: HTMLScriptElement | null = null;
    
      ngOnInit(): void {
        this.injectScript(this.clientId);
      }
    
      ngOnChanges(changes: SimpleChanges): void {
        if(changes['clientId'] && !changes['clientId'].firstChange) {
          this.removeScript();
          this.injectScript(this.clientId);
        }
      }
    
      ngOnDestroy(): void {
        this.removeScript();
      }
    
      private injectScript(clientId: string): void {
        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);
        this.scriptEl = script;
      }
    
      private removeScript(): void {
        if(this.scriptEl) {
          document.head.removeChild(this.scriptEl);
          this.scriptEl = null;
        }
      }
    }
  2. Import and use it in AppComponent

    Import MaisonChatComponent in your root AppComponent and bind your Client UUID.

    typescript
    // app.component.ts
    import { Component } from '@angular/core';
    import { MaisonChatComponent } from './maison-chat.component';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [MaisonChatComponent],
      templateUrl: './app.component.html',
    })
    export class AppComponent {
      readonly clientId = 'YOUR_CLIENT_UUID';
    }
    html
    <!-- app.component.html -->
    <app-maison-chat [clientId]="clientId" />
    <!-- rest of your app -->
  3. Build and run your application

    Run ng serve and open your app in the browser. The Maison chat icon should appear in the bottom-right corner within a few seconds.

  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 outside onload. initMcbs is not available until the bundle finishes loading. Always place the call inside script.onload.
Angular Universal (SSR). document is not available during server-side rendering. Guard DOM access with an isPlatformBrowser check from @angular/common when running in a Universal context.
ngOnChanges handles clientId updates. If your clientId changes at runtime (uncommon), the component automatically removes the old script and reinjects with the new ID via ngOnChanges.
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.