Blog
PRODUCT NEWSENGINEERING

Inbox SDKs for Vue and Angular: a native in-app notification center

Mike Miller

June 19, 2026

Inbox SDKs for Vue and Angular - blog header

Table of contents

What the Angular and Vue SDKs give you

Building custom UIs

What you can build

Works with your setup

Available now

The same drop-in inbox that powers React and JavaScript apps, now with first-class Angular and Vue components.

Courier Inbox now has native SDKs for Angular and Vue. You get the full notification center, toasts, and a preferences center as real components that fit your framework's conventions, not a generic web component you have to wrap yourself.

Building an in-app notification feed from scratch is more work than it looks. You need real-time updates over a WebSocket, read and unread state, archiving, pagination, tabs, theming, and a preferences UI so users can control what they receive. Until now, Angular and Vue teams either hand-rolled all of that or wrapped our framework-agnostic web components by hand. These SDKs do that wrapping for you, the right way for each framework.

What the Angular and Vue SDKs give you

Both SDKs wrap Courier Inbox, our drop-in in-app notification center, in idiomatic components and a programmatic layer. You install one package and get the inbox, toasts, and preferences, plus a way to build custom UIs when the defaults aren't enough.

A real-time inbox in a few lines

The headline component is the inbox itself. Import it, authenticate your user, and you have a working notification center with real-time updates, read and unread state, archiving, and infinite-scroll pagination.

In Angular, the components are standalone, so there's no NgModule to wire up. Import the component class, inject CourierService, and sign in:

Copied!

import { AfterViewInit, Component, inject } from "@angular/core";
import { CourierInboxComponent, CourierService } from "@trycourier/courier-angular";
@Component({
selector: "app-root",
standalone: true,
imports: [CourierInboxComponent],
template: `<courier-inbox></courier-inbox>`,
})
export class AppComponent implements AfterViewInit {
private readonly courier = inject(CourierService);
ngAfterViewInit(): void {
// Generate this JWT on your backend, never in client-side code
const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
this.courier.signIn({ userId: "your-user-id", jwt });
}
}

In Vue 3, the components are normal Vue components and the useCourier() composable handles auth:

Copied!

<script setup lang="ts">
import { onMounted } from "vue";
import { CourierInbox, useCourier } from "@trycourier/courier-vue";
const courier = useCourier();
onMounted(() => {
// Generate this JWT on your backend, never in client-side code
const jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
courier.shared.signIn({ userId: "your-user-id", jwt });
});
</script>
<template>
<CourierInbox />
</template>

The same JWT auth flow applies in both: your backend calls Courier's issue-token endpoint, returns the token to your client, and the SDK takes it from there. Your API keys never touch the browser.

Tabs, feeds, and filtering

Organize messages with feeds and tabs. A feed is a container that groups related tabs, and each tab is a filtered view. You can filter by tags, read or unread status, and archived state, and the filters combine with AND logic.

In Angular you pass them with the [feeds] input:

Copied!

feeds: CourierInboxFeed[] = [
{
feedId: "notifications",
title: "Notifications",
tabs: [
{ datasetId: "all-notifications", title: "All", filter: {} },
{ datasetId: "unread-notifications", title: "Unread", filter: { status: "unread" } },
{ datasetId: "important", title: "Important", filter: { tags: ["important"] } },
{ datasetId: "archived", title: "Archived", filter: { archived: true } },
],
},
];

Vue takes the same structure through the :feeds prop. If there's only one feed, the feed dropdown hides itself. If a feed has one tab, the tab bar disappears and the unread count sits next to the feed title. The defaults stay out of your way until you need the structure.

Toasts and a preferences center

Both SDKs include more than the feed. CourierToast (<courier-toast> in Angular, <CourierToast /> in Vue) shows short-lived notifications for time-sensitive alerts, with optional auto-dismiss and a countdown bar. It's connected to the same inbox message feed, so a toast and the inbox stay in sync.

CourierPreferences gives your users a built-in preferences center to manage which topics they're subscribed to and how each one is delivered, including per-channel routing and digest schedules. It needs a JWT with the read:preferences and write:preferences scopes, and that's the whole setup. You don't build a preferences UI, you embed one.

Theming that matches your app

Every component takes a theme object for light and dark modes. Pass it directly; the component serializes it for you. The theme covers the popup trigger button, the inbox header, feeds, tabs, the message list, and the loading, empty, and error states.

Copied!

theme: CourierInboxTheme = {
inbox: {
header: { filters: { unreadIndicator: { backgroundColor: "#8B5CF6" } } },
list: { item: { unreadIndicatorColor: "#8B5CF6" } },
},
};

The theme object is identical across every Courier Inbox SDK, so a theme you tuned for your React app drops straight into Angular or Vue. Helpers like defaultLightTheme, defaultDarkTheme, and mergeTheme let you start from the defaults and override only what you care about.

Building custom UIs

The ready-made components cover most cases. When you need full control, both SDKs expose the same data and actions the components use.

Angular ships an injectable CourierService that exposes auth, inbox, and toast state as RxJS observables, plus imperative methods for reading, archiving, and paginating messages. Vue ships the useCourier() composable, which returns the same shape with auth, inbox, and toast as Vue refs.

Here's the Vue composable driving a custom list:

Copied!

<script setup lang="ts">
import { onMounted } from "vue";
import { useCourier, defaultFeeds } from "@trycourier/courier-vue";
const { auth, inbox } = useCourier();
onMounted(async () => {
auth.value.signIn({ userId: "your-user-id", jwt: "eyJhbGci..." });
inbox.value.registerFeeds(defaultFeeds());
await inbox.value.listenForUpdates(); // required for real-time updates
await inbox.value.load();
});
</script>
<template>
<div>Total unread: {{ inbox.totalUnreadCount ?? 0 }}</div>
<ul>
<li v-for="message in inbox.feeds['all_messages']?.messages ?? []" :key="message.messageId">
{{ message.title }}
</li>
</ul>
</template>

One thing worth calling out: after you authenticate, call listenForUpdates() to open the WebSocket connection. Without it, the inbox shows only the messages from the initial load and won't update in real time. It's the most common reason a custom inbox looks frozen.

You can also mix the two approaches. Use the service or composable for state and the components for rendering. And when you need an imperative method that isn't exposed directly, you can reach the underlying web component: a @ViewChild ElementRef in Angular, or the getElement() method off a template ref in Vue.

What you can build

  • A notification bell with a popup feed. Use CourierInboxPopupMenu with a custom menu button that shows the unread count, aligned wherever your header needs it.
  • A full-page activity feed. Drop in CourierInbox with feeds for "All," "Mentions," and "Archived," and let pagination load more as the user scrolls.
  • Real-time toasts for live events. Render CourierToast for time-sensitive alerts with auto-dismiss, while the same messages collect in the inbox for later.
  • A self-serve preferences page. Embed CourierPreferences so users manage topics, channels, and digest schedules without a support ticket or a custom settings screen.

Each of these would normally mean building real-time sync, state management, and a theming system yourself. Here they're a component and a sign-in call.

Works with your setup

Both SDKs render client-side only and wire up after mount (ngAfterViewInit in Angular, onMounted in Vue), so they work with Angular Universal, Nuxt, and other SSR setups without extra configuration. They render once on the client and skip the server entirely.

Angular needs @angular/core, @angular/common (both 17 or later), and rxjs 7+. Vue needs Vue 3.3 or later. If your workspace runs on Courier's EU datacenter, both packages re-export getCourierApiUrlsForRegion so you can point signIn at the right endpoints.

Available now

The Angular and Vue inbox SDKs are available today on npm.

  1. Install the package for your framework:

Copied!

# Angular
npm install @trycourier/courier-angular
# Vue
npm install @trycourier/courier-vue
  1. Generate a JWT for your user on your backend with the inbox:read:messages and inbox:write:events scopes.
  2. Add the inbox component and call signIn.

Read the Angular SDK docs or the Vue SDK docs for the full component and API reference.

Already using a different framework? Nothing changes for you. The React SDK and the framework-agnostic @trycourier/courier-ui-inbox web components are still fully supported. The Angular and Vue packages share the same backend and theme system, so you can mix frameworks across apps and keep one consistent inbox experience.


Get started: Courier Inbox docs or the Angular and Vue SDK references.

Similar resources

product updates May 2026
Product NewsCourier UpdatesAI

What we shipped this month: May 2026 Edition

Courier shipped five launches in May 2026: AI Agent in Journeys (GA), the new Journeys API for code-driven flows, Custom Environments, Design Studio styling controls, and Courier Console v3. Each one closes a gap between writing software and shipping the messages that go with it.

By Kyle Seyler

May 20, 2026

AI Agent classify user branching
AIProduct News

Introducing the AI Node in Courier Journeys

The AI node is a new step inside Courier Journeys that classifies users, branches on the result, and writes per-channel copy from a single prompt. Here's what it does, how to set one up, and when it's worth using over a regular condition node.

By Kyle Seyler

May 14, 2026

claude design to courier ai
Customer JourneysAIProduct News

Using Claude Design, Claude Code, and Courier AI to Create a Multichannel Onboarding Series in 30 Minutes

A walkthrough of building a four-part multichannel onboarding series (email, in-app inbox, mobile push, and Slack) in 30 minutes using Claude Code and Cowork to orchestrate, Claude Design to mock each channel, the courier-template-builder skill to translate mocks into Elemental JSON, the Courier MCP to publish templates, and the Courier CLI to test sends. Covers the strategy behind the sequence and recommendations for anyone doing the same.

By Kyle Seyler

April 17, 2026

Multichannel Notifications Platform for SaaS

Products

Platform

Integrations

Customers

Blog

API Status

Subprocessors


© 2026 Courier. All rights reserved.