Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
cometchat avatar

Cometchat Angular Patterns

  • 4 installs
  • 70 repo stars
  • Updated June 23, 2026
  • cometchat/cometchat-skills

Angular-specific integration patterns for CometChat covering lazy loading, route guards, Router integration, APP_INITIALIZER setup, standalone vs NgModule, and SSR.

About

This skill teaches Angular-specific CometChat patterns: wiring init into the bootstrap lifecycle, lazy-loading the chat module, protecting routes with guards, and handling SSR/Universal. A developer uses it to integrate chat cleanly with Angular Router and bootstrap.

  • APP_INITIALIZER wiring, lazy loading, and route guards
  • Standalone vs NgModule and SSR/Universal considerations

Cometchat Angular Patterns by the numbers

  • 4 all-time installs (skills.sh)
  • Ranked #1,817 of 2,245 Frontend Development skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cometchat/cometchat-skills --skill cometchat-angular-patterns

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs4
repo stars70
Last updatedJune 23, 2026
Repositorycometchat/cometchat-skills

What it does

Angular-specific integration patterns for CometChat covering lazy loading, route guards, Router integration, APP_INITIALIZER setup, standalone vs NgModule, and SSR.

Files

SKILL.mdMarkdownGitHub ↗

Purpose

Teaches Claude Angular-specific integration patterns for CometChat — how to wire init into Angular's bootstrap lifecycle, lazy-load the chat module, protect chat routes with guards, handle SSR/Universal, and integrate with Angular Material. Assumes a working base integration (see cometchat-angular-core + cometchat-angular-placement).

Read `cometchat-angular-core` and `cometchat-angular-placement` first — this skill builds on top of the base integration.

Ground truth: docs/ui-kit/angular/getting-started, Angular Router docs, @cometchat/chat-uikit-angular@4.x exports.

---

1. APP_INITIALIZER pattern (production-grade init)

For production apps, use Angular's APP_INITIALIZER token to ensure CometChat is initialized before the app renders any component. This is cleaner than calling init() in AppComponent.ngOnInit().

// cometchat-init.service.ts
import { Injectable } from "@angular/core";
import { UIKitSettingsBuilder } from "@cometchat/uikit-shared";
import { CometChatUIKit } from "@cometchat/chat-uikit-angular";
import { environment } from "../environments/environment";

@Injectable({ providedIn: "root" })
export class CometChatInitService {
  private initialized = false;

  initialize(): Promise<void> {
    if (this.initialized) return Promise.resolve();

    const settings = new UIKitSettingsBuilder()
      .setAppId(environment.cometchat.appId)
      .setRegion(environment.cometchat.region)
      .setAuthKey(environment.cometchat.authKey)
      .subscribePresenceForAllUsers()
      .build();

    return CometChatUIKit.init(settings).then(() => {
      this.initialized = true;
    });
  }
}
// app.module.ts
import { APP_INITIALIZER, NgModule } from "@angular/core";
import { CometChatInitService } from "./cometchat-init.service";

export function initCometChat(service: CometChatInitService): () => Promise<void> {
  return () => service.initialize();
}

@NgModule({
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initCometChat,
      deps: [CometChatInitService],
      multi: true,
    },
  ],
})
export class AppModule {}

With APP_INITIALIZER, Angular waits for the init promise to resolve before bootstrapping the root component. No *ngIf="isReady" guard needed on the root template.

⚠️ `APP_INITIALIZER` blocks the entire app bootstrap. If CometChat init fails (network error, wrong credentials), the app never renders. Add error handling:

initialize(): Promise<void> {
  return CometChatUIKit.init(settings).then(() => {
    this.initialized = true;
  }).catch((err) => {
    console.error("CometChat init failed:", err);
    // Don't re-throw — let the app render and show an error state
  });
}

---

2. Route guard for authenticated chat

Protect chat routes so only logged-in users can access them.

// cometchat-auth.guard.ts
import { Injectable } from "@angular/core";
import { CanActivate, Router } from "@angular/router";
import { CometChatUIKit } from "@cometchat/chat-uikit-angular";

@Injectable({ providedIn: "root" })
export class CometChatAuthGuard implements CanActivate {
  constructor(private router: Router) {}

  canActivate(): Promise<boolean> {
    return CometChatUIKit.getLoggedinUser().then((user) => {
      if (user) return true;
      this.router.navigate(["/login"]);
      return false;
    });
  }
}
// app-routing.module.ts
import { CometChatAuthGuard } from "./cometchat-auth.guard";

export const routes: Routes = [
  {
    path: "chat",
    canActivate: [CometChatAuthGuard],
    loadChildren: () => import("./chat/chat.module").then((m) => m.ChatModule),
  },
  { path: "login", component: LoginComponent },
];

---

3. Lazy loading the chat module

For apps where chat is a secondary feature, lazy-load the CometChat module to keep the initial bundle small.

// chat/chat.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { CommonModule } from "@angular/common";
import {
  CometChatConversations,
  CometChatMessageHeader,
  CometChatMessageList,
  CometChatMessageComposer,
} from "@cometchat/chat-uikit-angular";
import { ConversationsComponent } from "./conversations/conversations.component";
import { MessagesComponent } from "./messages/messages.component";

const routes: Routes = [
  { path: "", component: ConversationsComponent },
  { path: "messages/user/:uid", component: MessagesComponent },
  { path: "messages/group/:guid", component: MessagesComponent },
];

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(routes),
    CometChatConversations,
    CometChatMessageHeader,
    CometChatMessageList,
    CometChatMessageComposer,
  ],
  declarations: [ConversationsComponent, MessagesComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class ChatModule {}
// app-routing.module.ts
export const routes: Routes = [
  {
    path: "chat",
    loadChildren: () => import("./chat/chat.module").then((m) => m.ChatModule),
  },
];

⚠️ CometChat init must still happen at the app root level, not inside the lazy-loaded module. The APP_INITIALIZER pattern (§ 1) or AppComponent.ngOnInit() ensures init completes before the lazy module loads.

---

Standalone components with Angular Router (Angular 14+)

For apps using standalone components (no NgModule), wire routing directly:

// main.ts
import { bootstrapApplication } from "@angular/platform-browser";
import { provideRouter } from "@angular/router";
import { provideAnimations } from "@angular/platform-browser/animations";
import { APP_INITIALIZER } from "@angular/core";
import { AppComponent } from "./app/app.component";
import { routes } from "./app/app.routes";
import { CometChatInitService } from "./app/cometchat-init.service";

bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(routes),
    provideAnimations(),
    {
      provide: APP_INITIALIZER,
      useFactory: (service: CometChatInitService) => () => service.initialize(),
      deps: [CometChatInitService],
      multi: true,
    },
  ],
});
// app.routes.ts
import { Routes } from "@angular/router";

export const routes: Routes = [
  {
    path: "chat",
    loadComponent: () =>
      import("./chat/conversations.component").then((m) => m.ConversationsComponent),
  },
  {
    path: "messages/user/:uid",
    loadComponent: () =>
      import("./chat/messages.component").then((m) => m.MessagesComponent),
  },
];

---

5. Login flow integration

Wire CometChat login to your app's existing auth flow.

Pattern A — Login on app startup (dev mode)

// app.component.ts
import { Component, OnInit } from "@angular/core";
import { CometChatUIKit } from "@cometchat/chat-uikit-angular";

@Component({ selector: "app-root", templateUrl: "./app.component.html" })
export class AppComponent implements OnInit {
  isReady = false;

  ngOnInit(): void {
    // CometChat.init() already called via APP_INITIALIZER
    CometChatUIKit.getLoggedinUser()
      .then((user) => {
        if (!user) {
          return CometChatUIKit.login({ uid: "cometchat-uid-1" });
        }
        return user;
      })
      .then(() => (this.isReady = true))
      .catch(console.error);
  }
}

Pattern B — Login after your app's auth (production)

// auth.service.ts
import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { CometChatUIKit } from "@cometchat/chat-uikit-angular";
import { environment } from "../environments/environment";

@Injectable({ providedIn: "root" })
export class AuthService {
  constructor(private http: HttpClient) {}

  loginWithCometChat(appJwt: string): Promise<void> {
    // 1. Fetch CometChat auth token from your backend
    return this.http
      .post<{ authToken: string }>(environment.cometchat.tokenEndpoint, {}, {
        headers: { Authorization: `Bearer ${appJwt}` },
      })
      .toPromise()
      .then((response) => {
        // 2. Login with the auth token
        return CometChatUIKit.login({ authToken: response!.authToken });
      })
      .then(() => {
        // 3. CometChat session established
      });
  }

  logout(): Promise<void> {
    return CometChatUIKit.logout();
  }
}

---

6. Angular Material integration

CometChat works alongside Angular Material. Common integration points:

Theming coexistence

CometChat uses its own CometChatThemeService — it does NOT read from Angular Material's theme. Set both independently:

// app.component.ts
import { Component } from "@angular/core";
import { CometChatThemeService } from "@cometchat/chat-uikit-angular";

@Component({ selector: "app-root", templateUrl: "./app.component.html" })
export class AppComponent {
  constructor(private cometChatTheme: CometChatThemeService) {
    // Set CometChat palette to match your Material theme's primary color
    cometChatTheme.theme.palette.setPrimary({ light: "#6200EE", dark: "#BB86FC" });
    cometChatTheme.theme.palette.setMode("light");
  }
}

MatSidenav + CometChat sidebar

<!-- app.component.html -->
<mat-sidenav-container style="height: 100vh;">
  <mat-sidenav mode="side" opened style="width: 320px;">
    <cometchat-conversations
      [onItemClick]="handleConvClick"
      style="height: 100%;"
    ></cometchat-conversations>
  </mat-sidenav>
  <mat-sidenav-content style="display: flex; flex-direction: column;">
    <cometchat-message-header [user]="selectedUser" [hideBackButton]="true"></cometchat-message-header>
    <cometchat-message-list [user]="selectedUser" style="flex: 1; overflow: hidden;"></cometchat-message-list>
    <cometchat-message-composer [user]="selectedUser"></cometchat-message-composer>
  </mat-sidenav-content>
</mat-sidenav-container>

---

7. SSR / Angular Universal considerations

CometChat's UI Kit uses browser APIs (window, document, localStorage) that are not available in Node.js during SSR. If the project uses Angular Universal:

// cometchat-init.service.ts
import { isPlatformBrowser } from "@angular/common";
import { PLATFORM_ID, Inject } from "@angular/core";

@Injectable({ providedIn: "root" })
export class CometChatInitService {
  constructor(@Inject(PLATFORM_ID) private platformId: object) {}

  initialize(): Promise<void> {
    // Skip CometChat init on the server
    if (!isPlatformBrowser(this.platformId)) {
      return Promise.resolve();
    }
    // ... normal init
  }
}
// In any component that renders CometChat components:
@Component({
  template: `
    <ng-container *ngIf="isBrowser">
      <cometchat-conversations></cometchat-conversations>
    </ng-container>
  `,
})
export class ChatComponent {
  isBrowser: boolean;
  constructor(@Inject(PLATFORM_ID) platformId: object) {
    this.isBrowser = isPlatformBrowser(platformId);
  }
}

⚠️ CometChat components must not render during SSR. They use browser APIs that throw in Node.js. Always guard with isPlatformBrowser().

---

8. Change detection optimization

CometChat components use Angular's default change detection. For performance-sensitive apps using OnPush:

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <cometchat-conversations
      [onItemClick]="handleConvClick"
    ></cometchat-conversations>
  `,
})
export class ChatComponent {
  constructor(private cdr: ChangeDetectorRef) {}

  handleConvClick = (conversation: CometChat.Conversation): void => {
    // Update component state
    this.selectedConversation = conversation;
    // Trigger change detection manually when using OnPush
    this.cdr.markForCheck();
  };
}

CometChat components themselves use default change detection internally — OnPush on the parent component is fine as long as you call markForCheck() after updating state from CometChat callbacks.

---

9. Anti-patterns

1. Do NOT call `CometChatUIKit.init()` inside a lazy-loaded module. Init must complete before any <cometchat-*> component renders. Use APP_INITIALIZER at the root level.

2. Do NOT use `ChangeDetectionStrategy.OnPush` without calling `markForCheck()` after CometChat callbacks. CometChat callbacks run outside Angular's zone — without markForCheck(), the view won't update.

3. Do NOT import CometChat components in `AppModule` if they're only used in a lazy-loaded feature module. Import them in the feature module to keep the initial bundle small.

4. Do NOT skip `isPlatformBrowser()` guard in SSR apps. CometChat uses browser APIs that crash in Node.js.

5. Do NOT use `window.location.reload()` after login. This is a common pattern in CometChat examples but it's an anti-pattern in Angular — use Angular Router navigation instead.

6. *Do NOT forget `CUSTOM_ELEMENTS_SCHEMA` in every module/component that uses `<cometchat->` tags.** Each standalone component and each NgModule needs it independently.

---

Skill routing reference

SkillWhen to route
cometchat-angular-coreInit, login, module setup — always first
cometchat-angular-componentsComponent prop reference
cometchat-angular-placementWhere to put chat (route / sidebar / modal / tab)
cometchat-angular-patternsThis skill — Angular-specific wiring (guards, lazy loading, SSR)
cometchat-angular-themingCometChatThemeService + palette
cometchat-angular-featuresCalls, extensions, AI
cometchat-angular-customizationCustom slot views, formatters, event bus
cometchat-angular-productionServer-minted auth tokens
cometchat-angular-troubleshootingBuild errors, runtime failures, SSR crashes

Related skills

Frontend Developmentfrontendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.