Capgo: push fixes to your Capacitor users in minutes, build signed iOS and Android apps without a Mac, and roll back in one click.
14-day unlimited free trial. No credit card required
🤖 Building with an AI coding agent? Install Capgo skills so Claude Code, Codex, Cursor, Copilot, or Gemini CLI know how to install and use
@capgo/capacitor-rich-notificationsin your Capacitor app:npx skills add Cap-go/capgo-skills. Then ask your agent: "Add @capgo/capacitor-rich-notifications to my Capacitor app and wire it up." Agent setup guides · Hosted MCP
Show polished local notifications from your Capacitor app: Android channels and groups, progress and ongoing alerts, big-text/picture/inbox layouts, action buttons with inline reply, exact scheduling, full-screen intents, and optional foreground-service promotion. It does not register for remote push (use @capgo/capacitor-notifications for FCM/APNs). Compared with the stock local notification APIs, you get one TypeScript surface for rich layouts, scheduling, tap/dismiss events, launch detection, and badges on iOS and Android (with a browser Notification fallback on web).
- Permissions -
checkPermission/requestPermissionfor notification access (including Android 13+POST_NOTIFICATIONS). - Android channels - Create channel groups, channels with importance/vibration/sound, and delete channels.
- Rich layouts - Big text, picture, and inbox styles; large images from HTTPS or data URLs.
- Progress and ongoing - Download-style progress bars and notifications that stay until you cancel them.
- Actions - Register reusable categories or attach per-notification buttons, including inline text reply.
- Scheduling - Fire once at a Unix timestamp or on a repeating interval (exact alarms on Android when permitted).
- Full-screen and FGS - Optional full-screen intent for calls/alarms and foreground-service notifications (Android, opt-in permissions).
- Lifecycle events -
pressanddismisslisteners, plusgetInitialNotificationwhen the app opens from a tap. - Badge - Set the app icon badge count on iOS.
- iOS polish -
UNUserNotificationCentercategories, interruption levels (passivethroughtimeSensitive), and scheduled triggers.
- File upload/download progress in the notification shade.
- Chat-style messages with a Reply action and inline text input.
- Reminders and snoozed tasks scheduled for a specific time or interval.
- Incoming call or alarm UI via full-screen intent on Android.
- Long-running tasks that must stay visible with a foreground service notification.
- Deep linking: read which notification (and action) launched the app.
| Plugin version | Capacitor compatibility | Maintained |
|---|---|---|
| v8.*.* | v8.*.* | ✅ |
| v7.*.* | v7.*.* | On demand |
| v6.*.* | v6.*.* | On demand |
Policy:
- New plugins start at version
8.0.0(Capacitor 8 baseline). - Backward compatibility for older Capacitor majors is supported on demand.
npm install @capgo/capacitor-rich-notifications
npx cap syncWith Bun:
bun add @capgo/capacitor-rich-notifications
bunx cap sync- Plugin docs on capgo.app
- Tutorial
- Capgo for live updates and plugin support
No custom Info.plist keys are required for standard local notifications. Call RichNotifications.requestPermission() before showing notifications. Register action categories with registerActions and reference categoryId on each notification. Use interruptionLevel for time-sensitive delivery on iOS 15+. The critical level requires Apple's Critical Alerts entitlement; without it, use timeSensitive or active.
The plugin library merges POST_NOTIFICATIONS into your app (required to post on Android 13+). Request runtime permission with requestPermission(). Minimum SDK: 24 (see the plugin android/build.gradle).
For exact alarms, full-screen intents, and foreground service notifications, add opt-in permissions and the foreground service to your app manifest. From your project root:
bun run scripts/apply-notification-permissions.mjs --project path/to/your-appThat helper adds SCHEDULE_EXACT_ALARM, USE_FULL_SCREEN_INTENT, FOREGROUND_SERVICE, FOREGROUND_SERVICE_SPECIAL_USE, and declares app.capgo.richnotifications.RichForegroundService with foregroundServiceType="specialUse". Create notification channels before posting (createChannel). Use foregroundService: true and fullScreen: true only when those permissions are present.
On web, the plugin uses the browser Notification API; schedule uses setTimeout and only runs while the page stays open. Channels, groups, fullScreen, and foregroundService are Android-only (no-ops or errors as documented in the API).
Request permission, create a channel on Android, show a notification, and listen for taps:
import { RichNotifications } from '@capgo/capacitor-rich-notifications';
await RichNotifications.requestPermission();
await RichNotifications.createChannel({
id: 'messages',
name: 'Messages',
importance: 'high',
});
const { id } = await RichNotifications.display({
title: 'Hello',
body: 'Tap to open the app',
channelId: 'messages',
});
await RichNotifications.addListener('press', (event) => {
console.log('pressed', event.id, event.actionId, event.input);
});
const launch = await RichNotifications.getInitialNotification();
if (launch.notification) {
console.log('opened from', launch.notification.id);
}Progress notification (Android):
await RichNotifications.display({
title: 'Downloading',
body: '42%',
channelId: 'messages',
ongoing: true,
progress: { current: 42, max: 100 },
});Schedule in 5 seconds:
await RichNotifications.schedule({
notification: {
title: 'Reminder',
body: 'Five seconds later',
channelId: 'messages',
},
trigger: { type: 'interval', interval: 5 },
});Inline reply action:
await RichNotifications.registerActions({
id: 'chat',
actions: [{ id: 'reply', title: 'Reply', input: { placeholder: 'Type a reply' } }],
});
await RichNotifications.display({
title: 'New message',
body: 'From Alex',
categoryId: 'chat',
channelId: 'messages',
});See example-app/ for a runnable demo (bun install and bun run start in that folder).
checkPermission()requestPermission()createChannel(...)createChannelGroup(...)deleteChannel(...)display(...)schedule(...)cancel(...)cancelAll()getDisplayed()getPending()getInitialNotification()setBadge(...)registerActions(...)getPluginVersion()addListener('press', ...)addListener('dismiss', ...)- Interfaces
- Type Aliases
Local rich notifications for Capacitor (no remote push).
Use @capgo/capacitor-notifications for FCM and APNs remote push.
checkPermission() => Promise<PermissionResult>Check the current local notification permission status without prompting.
Returns: Promise<PermissionResult>
Since: 8.0.0
requestPermission() => Promise<PermissionResult>Request local notification permission from the user.
On Android 13+, this maps to POST_NOTIFICATIONS. On iOS, uses UNUserNotificationCenter.
Returns: Promise<PermissionResult>
Since: 8.0.0
createChannel(channel: NotificationChannel) => Promise<void>Create an Android notification channel.
Resolves as a no-op on iOS and web.
| Param | Type |
|---|---|
channel |
NotificationChannel |
Since: 8.0.0
createChannelGroup(group: NotificationChannelGroup) => Promise<void>Create an Android notification channel group.
Resolves as a no-op on iOS and web.
| Param | Type |
|---|---|
group |
NotificationChannelGroup |
Since: 8.0.0
deleteChannel(options: NotificationIdOptions) => Promise<void>Delete an Android notification channel by id.
Resolves as a no-op on iOS and web.
| Param | Type |
|---|---|
options |
NotificationIdOptions |
Since: 8.0.0
display(notification: RichNotification) => Promise<NotificationIdResult>Display a local notification immediately.
Returns the notification id (generated when omitted in the payload).
| Param | Type |
|---|---|
notification |
RichNotification |
Returns: Promise<NotificationIdResult>
Since: 8.0.0
schedule(options: ScheduleOptions) => Promise<NotificationIdResult>Schedule a local notification for later.
On Android, exact timing may require SCHEDULE_EXACT_ALARM in the host app.
On web, scheduling uses setTimeout and only works while the page stays open.
| Param | Type |
|---|---|
options |
ScheduleOptions |
Returns: Promise<NotificationIdResult>
Since: 8.0.0
cancel(options: NotificationIdOptions) => Promise<void>Cancel a pending or displayed notification by id.
| Param | Type |
|---|---|
options |
NotificationIdOptions |
Since: 8.0.0
cancelAll() => Promise<void>Cancel every pending and displayed local notification managed by this plugin.
Since: 8.0.0
getDisplayed() => Promise<NotificationListResult>List notifications currently shown in the notification shade or Notification Center.
Returns: Promise<NotificationListResult>
Since: 8.0.0
getPending() => Promise<NotificationListResult>List notifications that are scheduled but not yet shown.
Returns: Promise<NotificationListResult>
Since: 8.0.0
getInitialNotification() => Promise<InitialNotificationResult>Return the notification that opened the app, if any.
Call early on startup to handle cold-start taps.
Returns: Promise<InitialNotificationResult>
Since: 8.0.0
setBadge(options: BadgeOptions) => Promise<void>Set the app icon badge count (iOS).
| Param | Type |
|---|---|
options |
BadgeOptions |
Since: 8.0.0
registerActions(options: RegisterActionsOptions) => Promise<void>Register a reusable action category (iOS UNNotificationCategory, Android action set).
Reference the same id in categoryId when displaying notifications.
| Param | Type |
|---|---|
options |
RegisterActionsOptions |
Since: 8.0.0
getPluginVersion() => Promise<PluginVersionResult>Returns the platform implementation version marker (native or web).
Returns: Promise<PluginVersionResult>
Since: 8.0.0
addListener(eventName: 'press', listenerFunc: (event: PressEvent) => void) => Promise<PluginListenerHandle>Listen for notification presses and action replies.
| Param | Type |
|---|---|
eventName |
'press' |
listenerFunc |
(event: PressEvent) => void |
Returns: Promise<PluginListenerHandle>
Since: 8.0.0
addListener(eventName: 'dismiss', listenerFunc: (event: DismissEvent) => void) => Promise<PluginListenerHandle>Listen for notification dismissals (swipe away on Android, dismiss on iOS where supported).
| Param | Type |
|---|---|
eventName |
'dismiss' |
listenerFunc |
(event: DismissEvent) => void |
Returns: Promise<PluginListenerHandle>
Since: 8.0.0
Permission check or request result.
| Prop | Type | Description |
|---|---|---|
status |
PermissionStatus |
Current permission status. |
Android notification channel definition (NotificationChannel).
| Prop | Type | Description | Default |
|---|---|---|---|
id |
string |
Unique channel id referenced by channelId on notifications. |
|
name |
string |
User-visible channel name. | |
description |
string |
Optional channel description shown in system settings. | |
importance |
ChannelImportance |
Channel importance. | "default" |
sound |
string |
Optional raw sound resource name in the Android app (res/raw). |
|
vibration |
boolean |
Whether the channel vibrates. | false |
Android notification channel group.
| Prop | Type | Description |
|---|---|---|
id |
string |
Unique group id referenced by groupId on notifications. |
name |
string |
User-visible group name in system settings. |
Identifier used by cancel and deleteChannel (channel id for deleteChannel).
| Prop | Type | Description |
|---|---|---|
id |
string |
Notification id to cancel, or Android channel id to delete. |
Result containing a notification id from display or schedule.
| Prop | Type | Description |
|---|---|---|
id |
string |
Notification id that was created or scheduled. |
Payload used to display or schedule a local notification.
| Prop | Type | Description | Default |
|---|---|---|---|
id |
string |
Notification id. A UUID string is generated when omitted. | |
title |
string |
Notification title (required). | |
body |
string |
Notification body text. | |
image |
string |
Large image as an https URL or data: URL (Android big picture / iOS attachment). |
|
badge |
number |
App icon badge count to apply when the notification is shown (iOS). | |
ongoing |
boolean |
Keep the notification until explicitly cancelled (Android ongoing notification). | false |
progress |
NotificationProgress |
Progress indicator for download or upload style notifications (Android). | |
fullScreen |
boolean |
Show as a full-screen intent suitable for calls or alarms (Android). Requires USE_FULL_SCREEN_INTENT in the host app. |
false |
foregroundService |
boolean |
Promote the notification to a foreground service (Android). Requires opt-in manifest permissions and RichForegroundService. |
false |
style |
NotificationStyle |
Expanded style layout (Android). Use lines when style is inbox. |
|
lines |
string[] |
Inbox lines when style is inbox. |
|
channelId |
string |
Android channel id (create with createChannel before posting). |
|
groupId |
string |
Android notification group id (optional grouping in the shade). | |
categoryId |
string |
iOS category id or Android registered action set id from registerActions. |
|
interruptionLevel |
InterruptionLevel |
iOS interruption level (iOS 15+). | "active" |
actions |
NotificationAction[] |
Actions attached only to this notification (in addition to categoryId actions). |
Progress bar shown on Android notifications.
| Prop | Type | Description | Default |
|---|---|---|---|
current |
number |
Current progress value (0 to max unless indeterminate is true). |
|
max |
number |
Maximum progress value. | 100 |
indeterminate |
boolean |
When true, shows an indeterminate progress indicator. | false |
A single notification action button (iOS UNNotificationAction, Android action).
| Prop | Type | Description |
|---|---|---|
id |
string |
Stable action identifier delivered in press events as actionId. |
title |
string |
Visible button title. |
input |
boolean | ActionInputOptions |
When true, shows a plain reply field. Pass an object to customize the placeholder. |
Inline reply configuration for an action button.
| Prop | Type | Description | Default |
|---|---|---|---|
placeholder |
string |
Placeholder shown in the reply field. | "Reply" on iOS when omitted |
Arguments for schedule.
| Prop | Type | Description |
|---|---|---|
notification |
RichNotification |
Notification payload to show when the trigger fires. |
trigger |
ScheduleTrigger |
When to show the notification. |
Schedule trigger that fires once at a Unix timestamp in milliseconds.
| Prop | Type | Description |
|---|---|---|
type |
'timestamp' |
Trigger kind discriminator. |
timestamp |
number |
Unix timestamp in milliseconds (Date.now() scale). |
Schedule trigger that fires after a delay in seconds.
| Prop | Type | Description | Default |
|---|---|---|---|
type |
'interval' |
Trigger kind discriminator. | |
interval |
number |
Delay in seconds before the first fire (minimum 1 second on iOS). | |
repeats |
boolean |
When true, keep repeating at the same interval. | false |
List of displayed or pending notifications.
| Prop | Type | Description |
|---|---|---|
notifications |
NotificationSummary[] |
Matching notifications. |
Summary of a displayed or pending notification.
| Prop | Type | Description |
|---|---|---|
id |
string |
Notification id. |
title |
string |
Title when the platform exposes it. |
Result of getInitialNotification.
| Prop | Type | Description |
|---|---|---|
notification |
InitialNotification | null |
Launch notification, or null when the app was not opened from one. |
Notification that opened the app, when available.
| Prop | Type | Description |
|---|---|---|
id |
string |
Notification id that opened the app. |
actionId |
string |
Action id when an action button was used. |
input |
string |
Inline reply text when the user submitted a text input action. |
Badge update payload for setBadge.
| Prop | Type | Description |
|---|---|---|
count |
number |
Badge count to display on the app icon (iOS). Use 0 to clear. |
Action category registration payload for registerActions.
| Prop | Type | Description |
|---|---|---|
id |
string |
Category or action-set id referenced by categoryId on notifications. |
actions |
NotificationAction[] |
Actions belonging to this category. |
Plugin version payload from getPluginVersion.
| Prop | Type | Description |
|---|---|---|
version |
string |
Version marker from the native implementation (for example native or web). |
| Prop | Type |
|---|---|
remove |
() => Promise<void> |
Event payload for the press listener (notification tap or action).
| Prop | Type | Description |
|---|---|---|
id |
string |
Notification id that was pressed. |
actionId |
string |
Action id when an action button or inline reply was used. |
input |
string |
Inline reply text when present. |
Event payload for the dismiss listener.
| Prop | Type | Description |
|---|---|---|
id |
string |
Notification id that was dismissed. |
Permission status returned by checkPermission and requestPermission.
'granted' | 'denied' | 'blocked' | 'unavailable'
Android notification channel importance levels (maps to NotificationManager importance).
'none' | 'min' | 'low' | 'default' | 'high' | 'max'
Expanded notification layout styles (Android NotificationCompat styles).
'bigtext' | 'picture' | 'inbox'
iOS interruption level for the notification (UNNotificationInterruptionLevel).
critical requires Apple's Critical Alerts entitlement.
'passive' | 'active' | 'timeSensitive' | 'critical'
Schedule trigger for local notifications.
