A Tauri v2 plugin for sending notifications on desktop and mobile platforms. Send toast notifications (brief auto-expiring OS window elements) with support for rich content, scheduling, actions, channels, and push delivery via FCM and APNs.
- Send simple and rich notifications
- Schedule notifications for specific dates or recurring intervals
- Interactive notifications with custom actions
- Notification channels (Android) for organized notifications
- Manage pending and active notifications
- Support for attachments, icons, and custom sounds
- Inbox and large text notification styles
- Group notifications with summary support
- Permission management
- Real-time notification events
- macOS: Native notification center integration
- Windows: Windows notification system
- Linux: notify-rust with desktop notification support
- iOS: User Notifications framework
- Android: Android notification system with channels
Install the JavaScript package:
npm install @choochmeque/tauri-plugin-notifications-api
# or
yarn add @choochmeque/tauri-plugin-notifications-api
# or
pnpm add @choochmeque/tauri-plugin-notifications-apiAdd the plugin to your Tauri project's Cargo.toml:
[dependencies]
tauri-plugin-notifications = "0.1"The push-notifications feature is disabled by default. To enable push notifications support:
[dependencies]
tauri-plugin-notifications = { version = "0.1", features = ["push-notifications"] }This enables:
- Firebase Cloud Messaging support on Android
- APNs (Apple Push Notification service) support on iOS
Note: Push notifications are currently supported on mobile platforms (iOS and Android) only. macOS and Windows support is not yet available.
Without this feature enabled:
- Firebase dependencies are not included in Android builds
- Push notification registration code is disabled
- The
registerForPushNotifications()function will return an error if called
Configure the plugin permissions in your capabilities/default.json:
{
"permissions": [
"notifications:default"
]
}Register the plugin in your Tauri app:
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_notifications::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}import {
isPermissionGranted,
requestPermission,
sendNotification
} from '@choochmeque/tauri-plugin-notifications-api';
// Check and request permission
let permissionGranted = await isPermissionGranted();
if (!permissionGranted) {
const permission = await requestPermission();
permissionGranted = permission === 'granted';
}
// Send simple notification
if (permissionGranted) {
sendNotification('Hello from Tauri!');
// Or with more details
sendNotification({
title: 'TAURI',
body: 'Tauri is awesome!'
});
}import { sendNotification } from '@choochmeque/tauri-plugin-notifications-api';
// Notification with icon and sound
await sendNotification({
id: 1,
title: 'New Message',
body: 'You have a new message from John',
icon: 'message_icon',
sound: 'notification_sound',
autoCancel: true
});
// Large text notification
await sendNotification({
id: 2,
title: 'Article',
body: 'New article available',
largeBody: 'This is a much longer text that will be displayed when the user expands the notification...',
summary: 'Read more'
});
// Inbox style notification
await sendNotification({
id: 3,
title: 'Email',
body: '3 new emails',
inboxLines: [
'Alice: Meeting at 3pm',
'Bob: Project update',
'Charlie: Lunch tomorrow?'
]
});import { sendNotification, Schedule } from '@choochmeque/tauri-plugin-notifications-api';
// Schedule notification for specific date
await sendNotification({
title: 'Reminder',
body: 'Time for your meeting!',
schedule: Schedule.at(new Date(2024, 0, 15, 14, 30))
});
// Repeating notification
await sendNotification({
title: 'Daily Reminder',
body: 'Don\'t forget to exercise!',
schedule: Schedule.at(new Date(2024, 0, 15, 9, 0), true)
});
// Schedule with interval
await sendNotification({
title: 'Break Time',
body: 'Time to take a break!',
schedule: Schedule.interval({
hour: 1
})
});
// Schedule every X units
import { ScheduleEvery } from '@choochmeque/tauri-plugin-notifications-api';
await sendNotification({
title: 'Hourly Update',
body: 'Checking in every hour',
schedule: Schedule.every(ScheduleEvery.Hour, 1)
});import {
sendNotification,
registerActionTypes,
onAction
} from '@choochmeque/tauri-plugin-notifications-api';
// Register action types
await registerActionTypes([{
id: 'message-actions',
actions: [
{
id: 'reply',
title: 'Reply',
input: true,
inputPlaceholder: 'Type your reply...',
inputButtonTitle: 'Send'
},
{
id: 'mark-read',
title: 'Mark as Read'
},
{
id: 'delete',
title: 'Delete',
destructive: true
}
]
}]);
// Send notification with actions
await sendNotification({
title: 'New Message',
body: 'You have a new message',
actionTypeId: 'message-actions'
});
// Listen for action events
const unlisten = await onAction((notification) => {
console.log('Action performed on notification:', notification);
});
// Stop listening
unlisten();import {
createChannel,
channels,
removeChannel,
Importance,
Visibility
} from '@choochmeque/tauri-plugin-notifications-api';
// Create a notification channel
await createChannel({
id: 'messages',
name: 'Messages',
description: 'Notifications for new messages',
importance: Importance.High,
visibility: Visibility.Private,
sound: 'message_sound',
vibration: true,
lights: true,
lightColor: '#FF0000'
});
// Send notification to specific channel
await sendNotification({
channelId: 'messages',
title: 'New Message',
body: 'You have a new message'
});
// List all channels
const channelList = await channels();
// Remove a channel
await removeChannel('messages');import {
pending,
active,
cancel,
cancelAll,
removeActive,
removeAllActive
} from '@choochmeque/tauri-plugin-notifications-api';
// Get pending notifications
const pendingNotifications = await pending();
// Cancel specific pending notifications
await cancel([1, 2, 3]);
// Cancel all pending notifications
await cancelAll();
// Get active notifications
const activeNotifications = await active();
// Remove specific active notifications
await removeActive([
{ id: 1 },
{ id: 2, tag: 'message' }
]);
// Remove all active notifications
await removeAllActive();import { onNotificationReceived } from '@choochmeque/tauri-plugin-notifications-api';
// Listen for notifications received
const unlisten = await onNotificationReceived((notification) => {
console.log('Notification received:', notification);
});
// Stop listening
unlisten();import { registerForPushNotifications } from '@choochmeque/tauri-plugin-notifications-api';
// Register for push notifications and get device token
try {
const token = await registerForPushNotifications();
console.log('Push token:', token);
// Send this token to your server to send push notifications
} catch (error) {
console.error('Failed to register for push notifications:', error);
}use tauri_plugin_notifications::{NotificationsExt, Schedule, ScheduleEvery};
// Send simple notification
app.notifications()
.builder()
.title("Hello")
.body("This is a notification from Rust!")
.show()?;
// Send rich notification
app.notifications()
.builder()
.id(1)
.title("New Message")
.body("You have a new message")
.icon("message_icon")
.sound("notification_sound")
.auto_cancel()
.show()?;
// Scheduled notification
app.notifications()
.builder()
.title("Reminder")
.body("Time for your meeting!")
.schedule(Schedule::at(date_time, false, false))
.show()?;
// Notification with attachments
use tauri_plugin_notifications::Attachment;
app.notifications()
.builder()
.title("Photo Shared")
.body("Check out this image!")
.attachment(Attachment {
id: "image1".to_string(),
url: "file:///path/to/image.jpg".to_string(),
})
.show()?;Checks if the permission to send notifications is granted.
Returns: Promise<boolean>
Requests the permission to send notifications.
Returns: Promise<'granted' | 'denied' | 'default'>
Registers the app for push notifications (mobile only). On Android, this retrieves the FCM device token. On iOS, this requests permissions and registers for remote notifications.
Returns: Promise<string> - The device push token
Sends a notification to the user. Can be called with a simple string for the title or with a detailed options object.
Parameters:
options: Notification options or title stringid: Notification identifier (32-bit integer)channelId: Channel identifier (Android)title: Notification titlebody: Notification bodyschedule: Schedule for delayed or recurring notificationslargeBody: Multiline text contentsummary: Detail text for large notificationsactionTypeId: Action type identifiergroup: Group identifiergroupSummary: Mark as group summary (Android)sound: Sound resource nameinboxLines: Array of lines for inbox style (max 5)icon: Notification iconlargeIcon: Large icon (Android)iconColor: Icon color (Android)attachments: Array of attachmentsextra: Extra payload dataongoing: Non-dismissible notification (Android)autoCancel: Auto-cancel on clicksilent: Silent notification (iOS)visibility: Notification visibilitynumber: Number of items (Android)
Register actions that are performed when the user clicks on the notification.
Parameters:
types: Array of action type objects with:id: Action type identifieractions: Array of action objectsid: Action identifiertitle: Action titlerequiresAuthentication: Requires device unlockforeground: Opens app in foregrounddestructive: Destructive action styleinput: Enable text inputinputButtonTitle: Input button labelinputPlaceholder: Input placeholder text
Retrieves the list of pending notifications.
Returns: Promise<PendingNotification[]>
Cancels the pending notifications with the given list of identifiers.
Cancels all pending notifications.
Retrieves the list of active notifications.
Returns: Promise<ActiveNotification[]>
Removes the active notifications with the given list of identifiers.
Removes all active notifications.
Creates a notification channel (Android).
Parameters:
channel: Channel configurationid: Channel identifiername: Channel namedescription: Channel descriptionsound: Sound resource namelights: Enable notification lightlightColor: Light colorvibration: Enable vibrationimportance: Importance level (None, Min, Low, Default, High)visibility: Visibility level (Secret, Private, Public)
Removes the channel with the given identifier.
Retrieves the list of notification channels.
Returns: Promise<Channel[]>
Listens for notification received events.
Returns: Promise<PluginListener> with unlisten() method
Listens for notification action performed events.
Returns: Promise<PluginListener> with unlisten() method
- Uses native notification systems
- Actions support varies by platform
- Limited scheduling capabilities on some platforms
- Channels not applicable (Android-specific)
- Requires permission request
- Rich notifications with attachments
- Action support with input options
- Silent notifications available
- Group notifications (thread identifiers)
- Notification channels required for Android 8.0+
- Full scheduling support
- Rich notification styles (inbox, large text)
- Ongoing notifications for background tasks
- Detailed importance and visibility controls
- Custom sounds, vibration, and lights
- The plugin automatically configures notification capabilities
- Add notification sounds to your Xcode project if needed:
- Add sound files to your iOS project
- Place in app bundle
- Reference by filename (without extension)
- The plugin automatically includes required permissions
- For custom sounds:
- Place sound files in
res/raw/folder - Reference by filename (without extension)
- Place sound files in
- For custom icons:
- Place icons in
res/drawable/folder - Reference by filename (without extension)
- Place icons in
- For push notifications (FCM) - These steps must be done in your Tauri app project:
- Create a Firebase project at Firebase Console
- Download the
google-services.jsonfile from Firebase Console - Place
google-services.jsonin your Tauri app'sgen/android/app/directory - Add the Google Services classpath to your app's
gen/android/build.gradle.kts:buildscript { repositories { google() mavenCentral() } dependencies { classpath("com.google.gms:google-services:4.4.2") } } - Apply the plugin at the bottom of
gen/android/app/build.gradle.kts:apply(plugin = "com.google.gms.google-services")
- The notification plugin already includes the Firebase Cloud Messaging dependency when the
push-notificationsfeature is enabled
- Notifications appear in the system notification center
- Test different notification types and interactions
- Verify notification persistence and dismissal
- Test on physical devices (simulator support is limited)
- Request permissions before sending notifications
- Test scheduled notifications with different intervals
- Verify action handling and notification grouping
- Create and test notification channels
- Test different importance levels and visibility settings
- Verify scheduled notifications work with device sleep
- Test ongoing notifications for background tasks
- Verify notification styles (inbox, large text, etc.)
- Verify permissions are granted
- On Android, ensure notification channel exists
- Check system notification settings
- Verify notification ID is unique
- Check device power settings (battery optimization)
- On Android, use
allowWhileIdlefor critical notifications - Verify schedule time is in the future
- Ensure action types are registered before sending notification
- Verify action IDs match between registration and handling
- Check platform-specific action support