CUSTOM_ELEMENTS_SCHEMA.
Installation
Basic Usage
Copy
import { Component, Input, ViewChild, ElementRef, AfterViewInit, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@mcp-b/char/web-component';
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
@Component({
selector: 'app-chat-widget',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `<char-agent #agent></char-agent>`,
})
export class ChatWidgetComponent implements AfterViewInit {
@Input() idToken!: string;
@Input() clientId!: string;
@ViewChild('agent') agentRef!: ElementRef<WebMCPAgentElement>;
ngAfterViewInit() {
this.agentRef.nativeElement.connect({ idToken: this.idToken, clientId: this.clientId });
}
}
With Reactive Updates
Handle token changes withngOnChanges:
Copy
import {
Component,
Input,
ViewChild,
ElementRef,
AfterViewInit,
OnChanges,
SimpleChanges,
CUSTOM_ELEMENTS_SCHEMA
} from '@angular/core';
import '@mcp-b/char/web-component';
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
@Component({
selector: 'app-chat-widget',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
@if (idToken) {
<char-agent #agent></char-agent>
}
`,
})
export class ChatWidgetComponent implements AfterViewInit, OnChanges {
@Input() idToken?: string;
@Input() clientId?: string;
@ViewChild('agent') agentRef?: ElementRef<WebMCPAgentElement>;
ngAfterViewInit() {
this.connectAgent();
}
ngOnChanges(changes: SimpleChanges) {
if (changes['idToken'] && !changes['idToken'].firstChange) {
this.connectAgent();
}
}
private connectAgent() {
if (this.idToken && this.clientId && this.agentRef) {
this.agentRef.nativeElement.connect({ idToken: this.idToken, clientId: this.clientId });
}
}
}
With NgRx Store
If using NgRx for state management:Copy
import { Component, ViewChild, ElementRef, AfterViewInit, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { Store } from '@ngrx/store';
import { selectIdToken } from './auth.selectors';
import '@mcp-b/char/web-component';
import type { WebMCPAgentElement } from '@mcp-b/char/web-component';
@Component({
selector: 'app-chat-widget',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
@if (idToken$ | async; as token) {
<char-agent #agent></char-agent>
}
`,
})
export class ChatWidgetComponent implements AfterViewInit {
@ViewChild('agent') agentRef?: ElementRef<WebMCPAgentElement>;
idToken$ = this.store.select(selectIdToken);
clientId = 'your-oidc-client-id';
constructor(private store: Store) {}
ngAfterViewInit() {
this.idToken$.subscribe(token => {
if (token && this.agentRef) {
this.agentRef.nativeElement.connect({ idToken: token, clientId: this.clientId });
}
});
}
}
Module-based Setup
For non-standalone components, add the schema to your module:Copy
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { ChatWidgetComponent } from './chat-widget.component';
@NgModule({
declarations: [ChatWidgetComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
exports: [ChatWidgetComponent],
})
export class ChatWidgetModule {}
See Also
- Identity Providers - Configure your IDP
- Embedding the Agent - Full embedding guide

