{"id":"24c289fc-41c2-4a8a-aef7-b802b2a9fb33","shortId":"ZWcXKS","kind":"skill","title":"cometchat-angular-patterns","tagline":"Angular-specific integration patterns for CometChat UI Kit v4 — lazy loading, route guards, Angular Router integration, APP_INITIALIZER setup, standalone vs NgModule, and SSR/Universal considerations.","description":"## Purpose\n\nTeaches 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`).\n\n**Read `cometchat-angular-core` and `cometchat-angular-placement` first** — this skill builds on top of the base integration.\n\nGround truth: `docs/ui-kit/angular/getting-started`, Angular Router docs, `@cometchat/chat-uikit-angular@4.x` exports.\n\n---\n\n## 1. APP_INITIALIZER pattern (production-grade init)\n\nFor 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()`.\n\n```typescript\n// cometchat-init.service.ts\nimport { Injectable } from \"@angular/core\";\nimport { UIKitSettingsBuilder } from \"@cometchat/uikit-shared\";\nimport { CometChatUIKit } from \"@cometchat/chat-uikit-angular\";\nimport { environment } from \"../environments/environment\";\n\n@Injectable({ providedIn: \"root\" })\nexport class CometChatInitService {\n  private initialized = false;\n\n  initialize(): Promise<void> {\n    if (this.initialized) return Promise.resolve();\n\n    const settings = new UIKitSettingsBuilder()\n      .setAppId(environment.cometchat.appId)\n      .setRegion(environment.cometchat.region)\n      .setAuthKey(environment.cometchat.authKey)\n      .subscribePresenceForAllUsers()\n      .build();\n\n    return CometChatUIKit.init(settings).then(() => {\n      this.initialized = true;\n    });\n  }\n}\n```\n\n```typescript\n// app.module.ts\nimport { APP_INITIALIZER, NgModule } from \"@angular/core\";\nimport { CometChatInitService } from \"./cometchat-init.service\";\n\nexport function initCometChat(service: CometChatInitService): () => Promise<void> {\n  return () => service.initialize();\n}\n\n@NgModule({\n  providers: [\n    {\n      provide: APP_INITIALIZER,\n      useFactory: initCometChat,\n      deps: [CometChatInitService],\n      multi: true,\n    },\n  ],\n})\nexport class AppModule {}\n```\n\nWith `APP_INITIALIZER`, Angular waits for the init promise to resolve before bootstrapping the root component. No `*ngIf=\"isReady\"` guard needed on the root template.\n\n**⚠️ `APP_INITIALIZER` blocks the entire app bootstrap.** If CometChat init fails (network error, wrong credentials), the app never renders. Add error handling:\n\n```typescript\ninitialize(): Promise<void> {\n  return CometChatUIKit.init(settings).then(() => {\n    this.initialized = true;\n  }).catch((err) => {\n    console.error(\"CometChat init failed:\", err);\n    // Don't re-throw — let the app render and show an error state\n  });\n}\n```\n\n---\n\n## 2. Route guard for authenticated chat\n\nProtect chat routes so only logged-in users can access them.\n\n```typescript\n// cometchat-auth.guard.ts\nimport { Injectable } from \"@angular/core\";\nimport { CanActivate, Router } from \"@angular/router\";\nimport { CometChatUIKit } from \"@cometchat/chat-uikit-angular\";\n\n@Injectable({ providedIn: \"root\" })\nexport class CometChatAuthGuard implements CanActivate {\n  constructor(private router: Router) {}\n\n  canActivate(): Promise<boolean> {\n    return CometChatUIKit.getLoggedinUser().then((user) => {\n      if (user) return true;\n      this.router.navigate([\"/login\"]);\n      return false;\n    });\n  }\n}\n```\n\n```typescript\n// app-routing.module.ts\nimport { CometChatAuthGuard } from \"./cometchat-auth.guard\";\n\nexport const routes: Routes = [\n  {\n    path: \"chat\",\n    canActivate: [CometChatAuthGuard],\n    loadChildren: () => import(\"./chat/chat.module\").then((m) => m.ChatModule),\n  },\n  { path: \"login\", component: LoginComponent },\n];\n```\n\n---\n\n## 3. Lazy loading the chat module\n\nFor apps where chat is a secondary feature, lazy-load the CometChat module to keep the initial bundle small.\n\n```typescript\n// chat/chat.module.ts\nimport { CUSTOM_ELEMENTS_SCHEMA, NgModule } from \"@angular/core\";\nimport { RouterModule, Routes } from \"@angular/router\";\nimport { CommonModule } from \"@angular/common\";\nimport {\n  CometChatConversations,\n  CometChatMessageHeader,\n  CometChatMessageList,\n  CometChatMessageComposer,\n} from \"@cometchat/chat-uikit-angular\";\nimport { ConversationsComponent } from \"./conversations/conversations.component\";\nimport { MessagesComponent } from \"./messages/messages.component\";\n\nconst routes: Routes = [\n  { path: \"\", component: ConversationsComponent },\n  { path: \"messages/user/:uid\", component: MessagesComponent },\n  { path: \"messages/group/:guid\", component: MessagesComponent },\n];\n\n@NgModule({\n  imports: [\n    CommonModule,\n    RouterModule.forChild(routes),\n    CometChatConversations,\n    CometChatMessageHeader,\n    CometChatMessageList,\n    CometChatMessageComposer,\n  ],\n  declarations: [ConversationsComponent, MessagesComponent],\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\n})\nexport class ChatModule {}\n```\n\n```typescript\n// app-routing.module.ts\nexport const routes: Routes = [\n  {\n    path: \"chat\",\n    loadChildren: () => import(\"./chat/chat.module\").then((m) => m.ChatModule),\n  },\n];\n```\n\n**⚠️ 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.\n\n---\n\n## Standalone components with Angular Router (Angular 14+)\n\nFor apps using standalone components (no NgModule), wire routing directly:\n\n```typescript\n// main.ts\nimport { bootstrapApplication } from \"@angular/platform-browser\";\nimport { provideRouter } from \"@angular/router\";\nimport { provideAnimations } from \"@angular/platform-browser/animations\";\nimport { APP_INITIALIZER } from \"@angular/core\";\nimport { AppComponent } from \"./app/app.component\";\nimport { routes } from \"./app/app.routes\";\nimport { CometChatInitService } from \"./app/cometchat-init.service\";\n\nbootstrapApplication(AppComponent, {\n  providers: [\n    provideRouter(routes),\n    provideAnimations(),\n    {\n      provide: APP_INITIALIZER,\n      useFactory: (service: CometChatInitService) => () => service.initialize(),\n      deps: [CometChatInitService],\n      multi: true,\n    },\n  ],\n});\n```\n\n```typescript\n// app.routes.ts\nimport { Routes } from \"@angular/router\";\n\nexport const routes: Routes = [\n  {\n    path: \"chat\",\n    loadComponent: () =>\n      import(\"./chat/conversations.component\").then((m) => m.ConversationsComponent),\n  },\n  {\n    path: \"messages/user/:uid\",\n    loadComponent: () =>\n      import(\"./chat/messages.component\").then((m) => m.MessagesComponent),\n  },\n];\n```\n\n---\n\n## 5. Login flow integration\n\nWire CometChat login to your app's existing auth flow.\n\n### Pattern A — Login on app startup (dev mode)\n\n```typescript\n// app.component.ts\nimport { Component, OnInit } from \"@angular/core\";\nimport { CometChatUIKit } from \"@cometchat/chat-uikit-angular\";\n\n@Component({ selector: \"app-root\", templateUrl: \"./app.component.html\" })\nexport class AppComponent implements OnInit {\n  isReady = false;\n\n  ngOnInit(): void {\n    // CometChat.init() already called via APP_INITIALIZER\n    CometChatUIKit.getLoggedinUser()\n      .then((user) => {\n        if (!user) {\n          return CometChatUIKit.login({ uid: \"cometchat-uid-1\" });\n        }\n        return user;\n      })\n      .then(() => (this.isReady = true))\n      .catch(console.error);\n  }\n}\n```\n\n### Pattern B — Login after your app's auth (production)\n\n```typescript\n// auth.service.ts\nimport { Injectable } from \"@angular/core\";\nimport { HttpClient } from \"@angular/common/http\";\nimport { CometChatUIKit } from \"@cometchat/chat-uikit-angular\";\nimport { environment } from \"../environments/environment\";\n\n@Injectable({ providedIn: \"root\" })\nexport class AuthService {\n  constructor(private http: HttpClient) {}\n\n  loginWithCometChat(appJwt: string): Promise<void> {\n    // 1. Fetch CometChat auth token from your backend\n    return this.http\n      .post<{ authToken: string }>(environment.cometchat.tokenEndpoint, {}, {\n        headers: { Authorization: `Bearer ${appJwt}` },\n      })\n      .toPromise()\n      .then((response) => {\n        // 2. Login with the auth token\n        return CometChatUIKit.login({ authToken: response!.authToken });\n      })\n      .then(() => {\n        // 3. CometChat session established\n      });\n  }\n\n  logout(): Promise<void> {\n    return CometChatUIKit.logout();\n  }\n}\n```\n\n---\n\n## 6. Angular Material integration\n\nCometChat works alongside Angular Material. Common integration points:\n\n### Theming coexistence\n\nCometChat uses its own `CometChatThemeService` — it does NOT read from Angular Material's theme. Set both independently:\n\n```typescript\n// app.component.ts\nimport { Component } from \"@angular/core\";\nimport { CometChatThemeService } from \"@cometchat/chat-uikit-angular\";\n\n@Component({ selector: \"app-root\", templateUrl: \"./app.component.html\" })\nexport class AppComponent {\n  constructor(private cometChatTheme: CometChatThemeService) {\n    // Set CometChat palette to match your Material theme's primary color\n    cometChatTheme.theme.palette.setPrimary({ light: \"#6200EE\", dark: \"#BB86FC\" });\n    cometChatTheme.theme.palette.setMode(\"light\");\n  }\n}\n```\n\n### MatSidenav + CometChat sidebar\n\n```html\n<!-- app.component.html -->\n<mat-sidenav-container style=\"height: 100vh;\">\n  <mat-sidenav mode=\"side\" opened style=\"width: 320px;\">\n    <cometchat-conversations\n      [onItemClick]=\"handleConvClick\"\n      style=\"height: 100%;\"\n    ></cometchat-conversations>\n  </mat-sidenav>\n  <mat-sidenav-content style=\"display: flex; flex-direction: column;\">\n    <cometchat-message-header [user]=\"selectedUser\" [hideBackButton]=\"true\"></cometchat-message-header>\n    <cometchat-message-list [user]=\"selectedUser\" style=\"flex: 1; overflow: hidden;\"></cometchat-message-list>\n    <cometchat-message-composer [user]=\"selectedUser\"></cometchat-message-composer>\n  </mat-sidenav-content>\n</mat-sidenav-container>\n```\n\n---\n\n## 7. SSR / Angular Universal considerations\n\nCometChat's UI Kit uses browser APIs (`window`, `document`, `localStorage`) that are not available in Node.js during SSR. If the project uses Angular Universal:\n\n```typescript\n// cometchat-init.service.ts\nimport { isPlatformBrowser } from \"@angular/common\";\nimport { PLATFORM_ID, Inject } from \"@angular/core\";\n\n@Injectable({ providedIn: \"root\" })\nexport class CometChatInitService {\n  constructor(@Inject(PLATFORM_ID) private platformId: object) {}\n\n  initialize(): Promise<void> {\n    // Skip CometChat init on the server\n    if (!isPlatformBrowser(this.platformId)) {\n      return Promise.resolve();\n    }\n    // ... normal init\n  }\n}\n```\n\n```typescript\n// In any component that renders CometChat components:\n@Component({\n  template: `\n    <ng-container *ngIf=\"isBrowser\">\n      <cometchat-conversations></cometchat-conversations>\n    </ng-container>\n  `,\n})\nexport class ChatComponent {\n  isBrowser: boolean;\n  constructor(@Inject(PLATFORM_ID) platformId: object) {\n    this.isBrowser = isPlatformBrowser(platformId);\n  }\n}\n```\n\n**⚠️ CometChat components must not render during SSR.** They use browser APIs that throw in Node.js. Always guard with `isPlatformBrowser()`.\n\n---\n\n## 8. Change detection optimization\n\nCometChat components use Angular's default change detection. For performance-sensitive apps using `OnPush`:\n\n```typescript\n@Component({\n  changeDetection: ChangeDetectionStrategy.OnPush,\n  template: `\n    <cometchat-conversations\n      [onItemClick]=\"handleConvClick\"\n    ></cometchat-conversations>\n  `,\n})\nexport class ChatComponent {\n  constructor(private cdr: ChangeDetectorRef) {}\n\n  handleConvClick = (conversation: CometChat.Conversation): void => {\n    // Update component state\n    this.selectedConversation = conversation;\n    // Trigger change detection manually when using OnPush\n    this.cdr.markForCheck();\n  };\n}\n```\n\nCometChat 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.\n\n---\n\n## 9. Anti-patterns\n\n1. **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.\n\n2. **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.\n\n3. **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.\n\n4. **Do NOT skip `isPlatformBrowser()` guard in SSR apps.** CometChat uses browser APIs that crash in Node.js.\n\n5. **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.\n\n6. **Do NOT forget `CUSTOM_ELEMENTS_SCHEMA` in every module/component that uses `<cometchat-*>` tags.** Each standalone component and each NgModule needs it independently.\n\n---\n\n## Skill routing reference\n\n| Skill | When to route |\n|---|---|\n| `cometchat-angular-core` | Init, login, module setup — always first |\n| `cometchat-angular-components` | Component prop reference |\n| `cometchat-angular-placement` | Where to put chat (route / sidebar / modal / tab) |\n| `cometchat-angular-patterns` | This skill — Angular-specific wiring (guards, lazy loading, SSR) |\n| `cometchat-angular-theming` | CometChatThemeService + palette |\n| `cometchat-angular-features` | Calls, extensions, AI |\n| `cometchat-angular-customization` | Custom slot views, formatters, event bus |\n| `cometchat-angular-production` | Server-minted auth tokens |\n| `cometchat-angular-troubleshooting` | Build errors, runtime failures, SSR crashes |","tags":["cometchat","angular","patterns","skills","agent-skills","ai-agent","chat","claude-code","cursor","messaging","nextjs","react"],"capabilities":["skill","source-cometchat","skill-cometchat-angular-patterns","topic-agent-skills","topic-ai-agent","topic-chat","topic-claude-code","topic-cometchat","topic-cursor","topic-messaging","topic-nextjs","topic-react","topic-react-native","topic-ui-kit"],"categories":["cometchat-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cometchat/cometchat-skills/cometchat-angular-patterns","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cometchat/cometchat-skills","source_repo":"https://github.com/cometchat/cometchat-skills","install_from":"skills.sh"}},"qualityScore":"0.463","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 27 github stars · SKILL.md body (13,850 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:04:48.226Z","embedding":null,"createdAt":"2026-05-07T13:05:07.570Z","updatedAt":"2026-05-18T19:04:48.226Z","lastSeenAt":"2026-05-18T19:04:48.226Z","tsv":"'/app.component.html':664,828 '/app/app.component':572 '/app/app.routes':576 '/app/cometchat-init.service':580 '/chat/chat.module':385,497 '/chat/conversations.component':612 '/chat/messages.component':621 '/cometchat-auth.guard':374 '/cometchat-init.service':210 '/conversations/conversations.component':447 '/environments/environment':165,725 '/login':366 '/messages/messages.component':451 '1':112,522,691,740,882,1092 '100':865 '14':539 '2':310,761,1118 '3':393,773,1143 '4':109,1175 '5':625,1192 '6':781,1221 '6200ee':849 '7':891 '8':1008 '9':1088 'access':326 'add':277 'ai':1306 'alongsid':787 'alreadi':675 'alway':1004,1259 'angular':3,6,19,35,46,66,76,80,85,90,105,124,236,536,538,782,788,805,893,918,1015,1133,1215,1217,1253,1263,1270,1282,1287,1296,1302,1309,1319,1328 'angular-specif':5,34,1286 'angular/common':436,925 'angular/common/http':717 'angular/core':153,206,333,427,568,653,713,817,931 'angular/platform-browser':555 'angular/platform-browser/animations':563 'angular/router':338,432,559,603 'anti':1090,1212 'anti-pattern':1089,1211 'api':902,999,1187 'app':22,113,122,126,136,202,222,234,258,263,274,303,400,508,519,541,565,588,634,643,661,678,704,825,1024,1112,1183 'app-root':660,824 'app-routing.module.ts':370,488 'app.component.ts':648,813 'app.module.ts':200 'app.routes.ts':599 'appcompon':570,582,667,831 'appcomponent.ngoninit':147,524 'appjwt':737,757 'appmodul':232,1150 'assum':68 'auth':637,706,743,765,1324 'auth.service.ts':709 'authent':314 'author':755 'authservic':731 'authtoken':751,769,771 'avail':909 'b':700 'backend':747 'base':71,100 'bb86fc':851 'bearer':756 'block':260 'boolean':979 'bootstrap':48,245,264 'bootstrapappl':553,581 'browser':901,998,1186 'build':95,192,1330 'bundl':417,1173 'bus':1316 'call':144,676,1080,1095,1124,1304 'callback':1087,1128,1130 'canactiv':335,350,355,381 'catch':289,697 'cdr':1042 'chang':1009,1018,1054,1066 'changedetect':1029 'changedetectionstrategy.onpush':1030,1122 'changedetectorref':1043 'chat':54,57,315,317,380,397,402,494,609,1275 'chat/chat.module.ts':420 'chatcompon':977,1039 'chatmodul':486 'class':170,231,347,485,666,730,830,936,976,1038 'claud':33 'cleaner':142 'coexist':794 'color':846 'cometchat':2,11,40,75,79,84,89,131,266,292,411,501,630,689,742,774,785,795,837,855,859,867,875,886,896,948,966,989,1012,1033,1061,1086,1108,1127,1129,1147,1184,1205,1233,1252,1262,1269,1281,1295,1301,1308,1318,1327 'cometchat-angular-compon':1261 'cometchat-angular-cor':74,83,1251 'cometchat-angular-custom':1307 'cometchat-angular-featur':1300 'cometchat-angular-pattern':1,1280 'cometchat-angular-plac':78,88,1268 'cometchat-angular-product':1317 'cometchat-angular-them':1294 'cometchat-angular-troubleshoot':1326 'cometchat-auth.guard.ts':329 'cometchat-convers':858,1032 'cometchat-init.service.ts':149,921 'cometchat-message-compos':885 'cometchat-message-head':866 'cometchat-message-list':874 'cometchat-uid':688 'cometchat.conversation':1046 'cometchat.init':674 'cometchat/chat-uikit-angular':108,161,342,443,657,721,821 'cometchat/uikit-shared':157 'cometchatauthguard':348,372,382 'cometchatconvers':438,473 'cometchatinitservic':171,208,215,227,578,592,595,937 'cometchatmessagecompos':441,476 'cometchatmessagehead':439,474 'cometchatmessagelist':440,475 'cometchatthem':834 'cometchattheme.theme.palette.setmode':852 'cometchattheme.theme.palette.setprimary':847 'cometchatthemeservic':799,819,835,1298 'cometchatuikit':159,340,655,719 'cometchatuikit.getloggedinuser':358,680 'cometchatuikit.init':194,284,1096 'cometchatuikit.login':686,768 'cometchatuikit.logout':780 'common':790,1202 'commonmodul':434,470 'complet':527,1105 'compon':139,248,391,456,461,466,534,544,650,658,815,822,963,967,968,990,1013,1028,1049,1062,1073,1109,1148,1237,1264,1265 'compos':888 'consider':30,895 'console.error':291,698 'const':181,376,452,490,605 'constructor':351,732,832,938,980,1040 'contain':972 'convers':860,1034,1045,1052 'conversationscompon':445,457,478 'core':77,86,1254 'crash':1189,1335 'credenti':272 'custom':422,481,1225,1310,1311 'dark':850 'declar':477 'default':1017,1065 'dep':226,594 'detect':1010,1019,1055,1067 'dev':645 'direct':549 'doc':107 'docs/ui-kit/angular/getting-started':104 'document':904 'element':423,482,1226 'ensur':130,525 'entir':262 'environ':163,723 'environment.cometchat.appid':186 'environment.cometchat.authkey':190 'environment.cometchat.region':188 'environment.cometchat.tokenendpoint':753 'err':290,295 'error':270,278,308,1331 'establish':776 'event':1315 'everi':1229 'exampl':1206 'exist':636 'export':111,169,211,230,346,375,484,489,604,665,729,829,935,975,1037 'extens':1305 'fail':268,294 'failur':1333 'fals':174,368,671 'featur':406,1161,1167,1303 'fetch':741 'fine':1075 'first':92,1260 'flex':881 'flow':627,638 'forget':1224 'formatt':1314 'function':212 'grade':118 'ground':102 'guard':18,60,252,312,1005,1180,1290 'guid':465 'handl':61,279 'handleconvclick':862,1036,1044 'happen':505 'header':754,869 'height':864 'hidden':884 'hidebackbutton':872 'html':857 'http':734 'httpclient':715,735 'id':928,941,983 'implement':349,668 'import':150,154,158,162,201,207,330,334,339,371,384,421,428,433,437,444,448,469,496,552,556,560,564,569,573,577,600,611,620,649,654,710,714,718,722,814,818,922,926,1146,1163 'independ':811,1243 'init':44,119,145,240,267,293,502,526,949,959,1103,1255 'initcometchat':213,225 'initi':23,114,127,133,173,175,203,223,235,259,281,416,520,566,589,679,945,1113,1172 'inject':151,166,331,343,711,726,929,932,939,981 'insid':512,1097 'instead':1220 'integr':8,21,37,64,72,101,628,784,791 'intern':1068 'isbrows':974,978 'isplatformbrows':923,954,987,1007,1179 'isreadi':251,670 'keep':414,1170 'kit':13,899 'lazi':15,51,394,408,515,530,1100,1159,1291 'lazy-load':50,407,514,1099,1158 'let':301 'level':510,1117 'lifecycl':49 'light':848,853 'list':877 'load':16,52,395,409,516,532,1101,1160,1292 'loadchildren':383,495 'loadcompon':610,619 'localstorag':905 'log':322 'logged-in':321 'login':390,626,631,641,701,762,1198,1256 'logincompon':392 'loginwithcometchat':736 'logout':777 'long':1077 'm':387,499,614,623 'm.chatmodule':388,500 'm.conversationscomponent':615 'm.messagescomponent':624 'main.ts':551 'manual':1056 'markforcheck':1081,1125,1137 'match':840 'materi':67,783,789,806,842 'matsidenav':854 'messag':868,876,887 'messages/group':464 'messages/user':459,617 'messagescompon':449,462,467,479 'mint':1323 'modal':1278 'mode':646 'modul':55,398,412,517,531,1102,1162,1168,1257 'module/component':1230 'multi':228,596 'must':503,991,1104 'navig':1219 'need':253,1241 'network':269 'never':275 'new':183 'ng':971 'ng-contain':970 'ngif':250,973 'ngmodul':27,204,219,425,468,546,1240 'ngoninit':672 'node.js':911,1003,1191 'normal':958 'object':944,985 'oninit':651,669 'onitemclick':861,1035 'onpush':1026,1059,1069 'optim':1011 'outsid':1132 'overflow':883 'palett':838,1299 'parent':1072 'path':379,389,455,458,463,493,608,616 'pattern':4,9,38,115,521,639,699,1091,1203,1213,1283 'perform':1022 'performance-sensit':1021 'placement':81,91,1271 'platform':927,940,982 'platformid':943,984,988 'point':792 'post':750 'primari':845 'privat':172,352,733,833,942,1041 'product':117,121,707,1320 'production-grad':116 'project':916 'promis':176,216,241,282,356,739,778,946 'promise.resolve':180,957 'prop':1266 'protect':56,316 'provid':220,221,583,587 'provideanim':561,586 'providedin':167,344,727,933 'providerout':557,584 'purpos':31 'put':1274 're':299,1153 're-throw':298 'read':82,803 'refer':1246,1267 'render':137,276,304,965,993,1110 'resolv':243 'respons':760,770 'return':179,193,217,283,357,363,367,685,692,748,767,779,956 'root':168,247,256,345,509,662,728,826,934,1116 'rout':17,58,311,318,377,378,430,453,454,472,491,492,548,574,585,601,606,607,1245,1250,1276 'router':20,106,336,353,354,537,1218 'routermodul':429 'routermodule.forchild':471 'run':1131 'runtim':1332 'schema':424,480,483,1227 'secondari':405 'see':73 'selectedus':871,879,890 'selector':659,823 'sensit':1023 'server':952,1322 'server-mint':1321 'servic':214,591 'service.initialize':218,593 'session':775 'set':182,195,285,809,836 'setappid':185 'setauthkey':189 'setregion':187 'setup':24,1258 'show':306 'sidebar':856,1277 'skill':94,1244,1247,1285 'skill-cometchat-angular-patterns' 'skip':947,1178 'slot':1312 'small':418,1174 'source-cometchat' 'specif':7,36,1288 'ssr':892,913,995,1182,1293,1334 'ssr/universal':29,62 'standalon':25,533,543,1236 'startup':644 'state':309,1050,1084 'still':504 'string':738,752 'style':863,880 'subscribepresenceforallus':191 'tab':1279 'tag':1234 'teach':32 'templat':257,969,1031 'templateurl':663,827 'theme':793,808,843,1297 'this.cdr.markforcheck':1060 'this.http':749 'this.initialized':178,197,287 'this.isbrowser':986 'this.isready':695 'this.platformid':955 'this.router.navigate':365 'this.selectedconversation':1051 'throw':300,1001 'token':128,744,766,1325 'top':97 'topic-agent-skills' 'topic-ai-agent' 'topic-chat' 'topic-claude-code' 'topic-cometchat' 'topic-cursor' 'topic-messaging' 'topic-nextjs' 'topic-react' 'topic-react-native' 'topic-ui-kit' 'topromis':758 'trigger':1053 'troubleshoot':1329 'true':198,229,288,364,597,696,873 'truth':103 'typescript':148,199,280,328,369,419,487,550,598,647,708,812,920,960,1027 'ui':12,898 'uid':460,618,687,690 'uikitsettingsbuild':155,184 'univers':894,919 'updat':1048,1083,1142 'use':123,542,796,900,917,997,1014,1025,1058,1064,1111,1121,1155,1185,1195,1216,1232 'usefactori':224,590 'user':324,360,362,682,684,693,870,878,889 'v4':14 'via':677 'view':1139,1313 'void':673,1047 'vs':26 'wait':237 'window':903 'window.location.reload':1196 'wire':43,547,629,1289 'without':1123,1136 'won':1140 'work':70,786 'wrong':271 'x':110 'zone':1135","prices":[{"id":"2186fbf7-8c97-410f-a087-ecbe63d2410f","listingId":"24c289fc-41c2-4a8a-aef7-b802b2a9fb33","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cometchat","category":"cometchat-skills","install_from":"skills.sh"},"createdAt":"2026-05-07T13:05:07.570Z"}],"sources":[{"listingId":"24c289fc-41c2-4a8a-aef7-b802b2a9fb33","source":"github","sourceId":"cometchat/cometchat-skills/cometchat-angular-patterns","sourceUrl":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-angular-patterns","isPrimary":false,"firstSeenAt":"2026-05-07T13:05:07.570Z","lastSeenAt":"2026-05-18T19:04:48.226Z"}],"details":{"listingId":"24c289fc-41c2-4a8a-aef7-b802b2a9fb33","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cometchat","slug":"cometchat-angular-patterns","github":{"repo":"cometchat/cometchat-skills","stars":27,"topics":["agent-skills","ai-agent","chat","claude-code","cometchat","cursor","messaging","nextjs","react","react-native","ui-kit"],"license":null,"html_url":"https://github.com/cometchat/cometchat-skills","pushed_at":"2026-05-18T05:04:24Z","description":"Add CometChat chat to any React, Next.js, React Native, Angular, Android, iOS, or Flutter project through your AI coding agent. Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and 50+ more agents.","skill_md_sha":"fcf70d1fc8682c186629f5fe1ebe07557318c2da","skill_md_path":"skills/cometchat-angular-patterns/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-angular-patterns"},"layout":"multi","source":"github","category":"cometchat-skills","frontmatter":{"name":"cometchat-angular-patterns","license":"MIT","description":"Angular-specific integration patterns for CometChat UI Kit v4 — lazy loading, route guards, Angular Router integration, APP_INITIALIZER setup, standalone vs NgModule, and SSR/Universal considerations.","compatibility":"Angular >=12 <=15; @cometchat/chat-uikit-angular ^4; @cometchat/chat-sdk-javascript ^4"},"skills_sh_url":"https://skills.sh/cometchat/cometchat-skills/cometchat-angular-patterns"},"updatedAt":"2026-05-18T19:04:48.226Z"}}