<courier-inbox>: inbox for displaying and managing messages<courier-inbox-popup-menu>: popup menu version of the inbox<courier-toast>: toast notifications for time-sensitive alerts<courier-preferences>: preference center for topic subscriptions and deliveryCourierService: injectable service for custom UIs
Installation
Available on GitHub and npm.@angular/core (>= 17), @angular/common (>= 17), and rxjs (>= 7) are peer dependencies.
The Courier Angular components are standalone. Import the component classes
(
CourierInboxComponent, CourierInboxPopupMenuComponent, CourierToastComponent,
CourierPreferencesComponent) directly into a component’s imports array, or into a
standalone bootstrap. No NgModule is required.Not using Angular? Use the
instead. Its elements work in any JavaScript project.
Authentication
Courier authenticates with a JWT that your backend mints with your Courier API key, never in client code. is the full guide: the token flow, scope strings, reading auth state, signing out, and token refresh. Using the EU datacenter? See .Quick start
ImportCourierInboxComponent into your standalone component. Inject CourierService to authenticate.
Component reference
Each component’s inputs, theme, outputs, and custom-render surface live with the feature. These links open on the Angular tab.
Angular takes the callbacks as outputs, not as props. Where the other web SDKs pass
onMessageClick, Angular binds (messageClick) and hands you the payload on $event. Every sample in the pages above shows the Angular form.
The CourierInboxTheme, CourierToastTheme, and CourierPreferencesTheme objects are the same on React, Vue, Angular, and the Web Components, so each is documented once: , , .
CourierService
The injectableCourierService gives you programmatic access to Courier. Use it to build custom UIs. It exposes auth/inbox/toast state as RxJS observables plus imperative action methods. Inject it with inject(CourierService) or constructor injection. It is providedIn: "root".
When to use the service vs components
- Components (
<courier-inbox>,<courier-toast>): quick integration with the default UI - Service (
CourierService): custom UIs, programmatic control, state management - Both together: the service manages state, components render
Reactive state
Call
listenForUpdates() after authentication to open the realtime connection. Without it, the inbox loads once from the initial fetch and doesn’t update again.
Complete example: authentication, inbox setup, real-time updates, and displaying messages with the async pipe:
Methods
The service flattens what the other web SDKs nest. Where React reads
inbox.readMessage(message), Angular calls courier.readMessage(message) and reads the data off inbox$. covers what each one does.
Advanced
Custom-element schema
The Courier Angular components render native custom elements internally. They are self-contained standalone components, so you don’t needCUSTOM_ELEMENTS_SCHEMA in your own components. Import the component classes.
Server-side rendering
Courier Inbox and Toast render client-side only. They wire up inngAfterViewInit, which doesn’t run on the server. They work with Angular Universal / SSR setups, rendering once on the client.
Troubleshooting
Inbox not updating in real-time
Inbox not updating in real-time
Call
listenForUpdates() on CourierService after authentication. It opens the WebSocket connection required for real-time updates.Messages not loading
Messages not loading
Possible causes:
- Not authenticated: call
signIn() - Feeds not registered: call
registerFeeds()beforeload() - Network errors: subscribe to
inbox$and check itserror - JWT expired: generate a new token
Authentication errors
Authentication errors
- Invalid JWT: generate the JWT correctly on your backend
- Expired JWT: JWTs expire. Generate a new one
- Missing scopes: include
inbox:read:messagesandinbox:write:eventsin the JWT - Wrong user ID: the
userIdmust match the user the JWT was issued for
Custom slots not rendering
Custom slots not rendering
Custom render slots are named
<ng-template> children (e.g. <ng-template #listItem let-props>), read by the component via @ContentChild. The ref name must match exactly: #header, #listItem, #emptyState, #loadingState, #errorState, #paginationItem, #menuButton, #toastItem, #toastItemContent.TypeScript errors
TypeScript errors
Import types directly from the package:
Best practices
- JWT security: always generate JWTs server-side. Cache on the client, refresh before expiration (standard:
'1d'), and include only the scopes you need. - Performance:
canUseCache: true(default) serves cached data. Set a suitablesetPaginationLimit(). Prefer theasyncpipe over manual subscriptions so Angular manages teardown. - Testing: provide a mock
CourierServiceinTestBedto return test data: