Skip to main content
The Angular SDK wraps Courier’s in-app components as standalone Angular components, plus an injectable service that exposes the client behind them.
  • <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 delivery
  • CourierService: injectable service for custom UIs
See these components in the interactive Inbox demo. No setup required.

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

Import CourierInboxComponent into your standalone component. Inject CourierService to authenticate.
Follow the for step-by-step guidance, including backend JWT generation.

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 injectable CourierService 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 need CUSTOM_ELEMENTS_SCHEMA in your own components. Import the component classes.

Server-side rendering

Courier Inbox and Toast render client-side only. They wire up in ngAfterViewInit, which doesn’t run on the server. They work with Angular Universal / SSR setups, rendering once on the client.

Troubleshooting

Call listenForUpdates() on CourierService after authentication. It opens the WebSocket connection required for real-time updates.
Possible causes:
  1. Not authenticated: call signIn()
  2. Feeds not registered: call registerFeeds() before load()
  3. Network errors: subscribe to inbox$ and check its error
  4. JWT expired: generate a new token
  • Invalid JWT: generate the JWT correctly on your backend
  • Expired JWT: JWTs expire. Generate a new one
  • Missing scopes: include inbox:read:messages and inbox:write:events in the JWT
  • Wrong user ID: the userId must match the user the JWT was issued for
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.
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 suitable setPaginationLimit(). Prefer the async pipe over manual subscriptions so Angular manages teardown.
  • Testing: provide a mock CourierService in TestBed to return test data:

TypeScript types