Skip to main content
Version: Next Version ๐Ÿšง

Notification

This part of the runtime provides access to native system notifications with support for interactive elements like action buttons and text input fields.

InitializeNotificationsโ€‹

Initializes the notification system. It should be called during app startup.

Go: InitializeNotifications(ctx context.Context) error

JavaScript: InitializeNotifications(): Promise<void>

Returns: Error if initialization fails

Example:

err := runtime.InitializeNotifications(ctx)
if err != nil {
log.Fatal(err)
}
await runtime.InitializeNotifications();

IsNotificationAvailableโ€‹

Checks if notifications are supported on the current platform.

Go: IsNotificationAvailable(ctx context.Context) bool

JavaScript: IsNotificationAvailable(): Promise<boolean>

Returns: true if notifications are supported, false otherwise

Example:

if !runtime.IsNotificationAvailable(ctx) {
log.Println("Notifications not available on this platform")
}
const available = await runtime.IsNotificationAvailable();
if (!available) {
console.log("Notifications not available on this platform");
}

RequestNotificationAuthorizationโ€‹

Requests permission to display notifications (macOS only). On Windows and Linux, this always returns true.

Go: RequestNotificationAuthorization(ctx context.Context) (bool, error)

JavaScript: RequestNotificationAuthorization(): Promise<boolean>

Returns: Authorization status and error

Example:

authorized, err := runtime.RequestNotificationAuthorization(ctx)
const authorized = await runtime.RequestNotificationAuthorization();

CheckNotificationAuthorizationโ€‹

Checks the current notification authorization status (macOS only). On Windows and Linux, this always returns true.

Go: CheckNotificationAuthorization(ctx context.Context) (bool, error)

JavaScript: CheckNotificationAuthorization(): Promise<boolean>

Returns: Authorization status and error

Example:

authorized, err := runtime.CheckNotificationAuthorization(ctx)
const authorized = await runtime.CheckNotificationAuthorization();

CleanupNotificationsโ€‹

Cleans up notification resources and releases any held connections. This should be called when shutting down the application, particularly on Linux where it closes the D-Bus connection.

Go: CleanupNotifications(ctx context.Context)

JavaScript: CleanupNotifications(): Promise<void>

Example:

runtime.CleanupNotifications(ctx)
await runtime.CleanupNotifications();

SendNotificationโ€‹

Sends a basic notification to the system.

Go: SendNotification(ctx context.Context, options NotificationOptions) error

JavaScript: SendNotification(options: NotificationOptions): Promise<void>

Returns: Error if the notification fails to send

Example:

err := runtime.SendNotification(ctx, runtime.NotificationOptions{
ID: "notif-1",
Title: "Hello",
Body: "This is a notification",
})
await runtime.SendNotification({
id: "notif-1",
title: "Hello",
body: "This is a notification"
});

SendNotificationWithActionsโ€‹

Sends an interactive notification with predefined actions. Requires a registered notification category. If the category is not found or CategoryID is empty, a basic notification will be sent instead.

Go: SendNotificationWithActions(ctx context.Context, options NotificationOptions) error

JavaScript: SendNotificationWithActions(options: NotificationOptions): Promise<void>

Returns: Error if the notification fails to send

Example:

err := runtime.SendNotificationWithActions(ctx, runtime.NotificationOptions{
ID: "notif-2",
Title: "Task Reminder",
Body: "Complete your task",
CategoryID: "TASK_CATEGORY",
})
await runtime.SendNotificationWithActions({
id: "notif-2",
title: "Task Reminder",
body: "Complete your task",
categoryId: "TASK_CATEGORY"
});

RegisterNotificationCategoryโ€‹

Registers a notification category that can be used with interactive notifications. Registering a category with the same ID as a previously registered category will override it.

Go: RegisterNotificationCategory(ctx context.Context, category NotificationCategory) error

JavaScript: RegisterNotificationCategory(category: NotificationCategory): Promise<void>

Returns: Error if registration fails

Example:

err := runtime.RegisterNotificationCategory(ctx, runtime.NotificationCategory{
ID: "TASK_CATEGORY",
Actions: []runtime.NotificationAction{
{ID: "COMPLETE", Title: "Complete"},
{ID: "CANCEL", Title: "Cancel"},
},
})
await runtime.RegisterNotificationCategory({
id: "TASK_CATEGORY",
actions: [
{id: "COMPLETE", title: "Complete"},
{id: "CANCEL", title: "Cancel"}
]
});

RemoveNotificationCategoryโ€‹

Removes a previously registered notification category.

Go: RemoveNotificationCategory(ctx context.Context, categoryId string) error

JavaScript: RemoveNotificationCategory(categoryId: string): Promise<void>

Returns: Error if removal fails

Example:

err := runtime.RemoveNotificationCategory(ctx, "TASK_CATEGORY")
await runtime.RemoveNotificationCategory("TASK_CATEGORY");

RemoveAllPendingNotificationsโ€‹

Removes all pending notifications (macOS and Linux only).

Go: RemoveAllPendingNotifications(ctx context.Context) error

JavaScript: RemoveAllPendingNotifications(): Promise<void>

Returns: Error if removal fails

Example:

err := runtime.RemoveAllPendingNotifications(ctx)
await runtime.RemoveAllPendingNotifications();

RemovePendingNotificationโ€‹

Removes a specific pending notification (macOS and Linux only).

Go: RemovePendingNotification(ctx context.Context, identifier string) error

JavaScript: RemovePendingNotification(identifier: string): Promise<void>

Returns: Error if removal fails

Example:

err := runtime.RemovePendingNotification(ctx, "notif-1")
await runtime.RemovePendingNotification("notif-1");

RemoveAllDeliveredNotificationsโ€‹

Removes all delivered notifications (macOS and Linux only).

Go: RemoveAllDeliveredNotifications(ctx context.Context) error

JavaScript: RemoveAllDeliveredNotifications(): Promise<void>

Returns: Error if removal fails

Example:

err := runtime.RemoveAllDeliveredNotifications(ctx)
await runtime.RemoveAllDeliveredNotifications();

RemoveDeliveredNotificationโ€‹

Removes a specific delivered notification (macOS and Linux only).

Go: RemoveDeliveredNotification(ctx context.Context, identifier string) error

JavaScript: RemoveDeliveredNotification(identifier: string): Promise<void>

Returns: Error if removal fails

Example:

err := runtime.RemoveDeliveredNotification(ctx, "notif-1")
await runtime.RemoveDeliveredNotification("notif-1");

RemoveNotificationโ€‹

Removes a notification by identifier (Linux only). On macOS and Windows, this is a stub that always returns nil.

Go: RemoveNotification(ctx context.Context, identifier string) error

JavaScript: RemoveNotification(identifier: string): Promise<void>

Returns: Error if removal fails

Example:

err := runtime.RemoveNotification(ctx, "notif-1")
await runtime.RemoveNotification("notif-1");

OnNotificationResponseโ€‹

Registers a callback function to handle notification responses when users interact with notifications.

Go: OnNotificationResponse(ctx context.Context, callback func(result NotificationResult))

JavaScript

OnNotificationResponse is not available in the JavaScript runtime. Instead, JavaScript applications should use the Events API to listen for notification responses. From your Go callback, emit an event that your JavaScript code can listen to.

Example:

runtime.OnNotificationResponse(ctx, func(result runtime.NotificationResult) {
if result.Error != nil {
return
}
// Emit an event that JavaScript can listen to
runtime.EventsEmit(ctx, "notification-response", result.Response)
})
runtime.EventsOn("notification-response", (response) => {
console.log("Notification response:", response);
switch (response.actionIdentifier) {
case "COMPLETE":
// Handle complete action
break;
case "CANCEL":
// Handle cancel action
break;
}
});

Optionsโ€‹

NotificationOptionsโ€‹

Go:

type NotificationOptions struct {
ID string `json:"id"`
Title string `json:"title"`
Subtitle string `json:"subtitle,omitempty"` // (macOS and Linux only)
Body string `json:"body,omitempty"`
CategoryID string `json:"categoryId,omitempty"`
Data map[string]interface{} `json:"data,omitempty"`
}

TypeScript:

interface NotificationOptions {
id: string;
title: string;
subtitle?: string; // macOS and Linux only
body?: string;
categoryId?: string;
data?: { [key: string]: any };
}
FieldDescriptionWinMacLin
IDUnique identifier for the notificationโœ…โœ…โœ…
TitleMain notification titleโœ…โœ…โœ…
SubtitleSubtitle text (macOS and Linux only)โœ…โœ…
BodyMain notification contentโœ…โœ…โœ…
CategoryIDCategory identifier for interactive notificationsโœ…โœ…โœ…
DataCustom data to associate with the notificationโœ…โœ…โœ…

NotificationCategoryโ€‹

Go:

type NotificationCategory struct {
ID string `json:"id,omitempty"`
Actions []NotificationAction `json:"actions,omitempty"`
HasReplyField bool `json:"hasReplyField,omitempty"`
ReplyPlaceholder string `json:"replyPlaceholder,omitempty"`
ReplyButtonTitle string `json:"replyButtonTitle,omitempty"`
}

TypeScript:

interface NotificationCategory {
id?: string;
actions?: NotificationAction[];
hasReplyField?: boolean;
replyPlaceholder?: string;
replyButtonTitle?: string;
}
FieldDescriptionWinMacLin
IDUnique identifier for the categoryโœ…โœ…โœ…
ActionsArray of action buttonsโœ…โœ…โœ…
HasReplyFieldWhether to include a text input fieldโœ…โœ…
ReplyPlaceholderPlaceholder text for the input fieldโœ…โœ…
ReplyButtonTitleText for the reply buttonโœ…โœ…

NotificationActionโ€‹

Go:

type NotificationAction struct {
ID string `json:"id,omitempty"`
Title string `json:"title,omitempty"`
Destructive bool `json:"destructive,omitempty"` // (macOS-specific)
}

TypeScript:

interface NotificationAction {
id?: string;
title?: string;
destructive?: boolean; // macOS-specific
}
FieldDescriptionWinMacLin
IDUnique identifier for the actionโœ…โœ…โœ…
TitleButton textโœ…โœ…โœ…
DestructiveWhether the action is destructive (macOS-only)โœ…

macOS-specific Behaviorโ€‹

On macOS, the Destructive flag causes the action button to appear in red, indicating it's a destructive action (like delete or cancel). On Windows and Linux, this flag is ignored.

Example:

actions := []runtime.NotificationAction{
{ID: "SAVE", Title: "Save"},
{ID: "DELETE", Title: "Delete", Destructive: true}, // Shows as red button on macOS
}

NotificationResponseโ€‹

type NotificationResponse struct {
ID string `json:"id,omitempty"`
ActionIdentifier string `json:"actionIdentifier,omitempty"`
CategoryID string `json:"categoryId,omitempty"` // Consistent with NotificationOptions
Title string `json:"title,omitempty"`
Subtitle string `json:"subtitle,omitempty"` // (macOS and Linux only)
Body string `json:"body,omitempty"`
UserText string `json:"userText,omitempty"`
UserInfo map[string]interface{} `json:"userInfo,omitempty"`
}
FieldDescriptionWinMacLin
IDNotification identifierโœ…โœ…โœ…
ActionIdentifierAction that was triggeredโœ…โœ…โœ…
CategoryIDCategory of the notificationโœ…โœ…โœ…
TitleTitle of the notificationโœ…โœ…โœ…
SubtitleSubtitle of the notification (macOS and Linux only)โœ…โœ…
BodyBody text of the notificationโœ…โœ…โœ…
UserTextText entered by the userโœ…โœ…
UserInfoCustom data from the notificationโœ…โœ…โœ…

NotificationResultโ€‹

type NotificationResult struct {
Response NotificationResponse
Error error
}
FieldDescription
ResponseThe notification response data
ErrorAny error that occurred during the interaction

Platform-Specific Behaviorโ€‹

macOSโ€‹

  • Authorization Required: Apps must request notification permission before sending notifications
  • Notarization: Apps must be notarized for distribution
  • Features: All features supported including subtitles, text input, and destructive actions
  • Styling: Automatically adapts to system dark/light mode
  • Center: Notifications appear in macOS Notification Center

Example:

// Check and request authorization
authorized, err := runtime.CheckNotificationAuthorization(ctx)
if err != nil {
return err
}

if !authorized {
authorized, err = runtime.RequestNotificationAuthorization(ctx)
if err != nil || !authorized {
return fmt.Errorf("notification authorization denied")
}
}

// Now send notifications
// Check and request authorization
let authorized = await runtime.CheckNotificationAuthorization();
if (!authorized) {
authorized = await runtime.RequestNotificationAuthorization();
if (!authorized) {
throw new Error("Notification authorization denied");
}
}

// Now send notifications

Windowsโ€‹

  • No Authorization: Permission system not required
  • Features: Supports text input and high DPI displays
  • Limitations: Subtitle not supported
  • Styling: Adapts to Windows theme settings
  • Behavior: Uses Windows toast notification system

Linuxโ€‹

  • Desktop Environment Dependent: Behavior varies by DE (GNOME, KDE, XFCE, etc.)
  • Features: Supports subtitles
  • Limitations: User text input not supported
  • Styling: Follows desktop environment theme
  • Behavior: Uses native notification system when available

Example:

// Check system support
if !runtime.IsNotificationAvailable(ctx) {
return fmt.Errorf("notifications not supported on this Linux desktop")
}

// Linux notifications may not support text input
// Only use actions that don't require user text
// Check system support
const available = await runtime.IsNotificationAvailable();
if (!available) {
throw new Error("Notifications not supported on this Linux desktop");
}

// Linux notifications may not support text input
// Only use actions that don't require user text

Action Identifiersโ€‹

When handling notification responses, these special action identifiers may be present:

  • DEFAULT_ACTION: Triggered when the user clicks the notification itself (not an action button)
  • TEXT_REPLY: Triggered when the user submits text via the reply field

Example response handling:

runtime.OnNotificationResponse(ctx, func(result runtime.NotificationResult) {
if result.Error != nil {
fmt.Printf("Response error: %v\n", result.Error)
return
}

response := result.Response
switch response.ActionIdentifier {
case "DEFAULT_ACTION":
fmt.Println("User clicked the notification")
case "TEXT_REPLY":
fmt.Printf("User replied: %s\n", response.UserText)
case "COMPLETE":
fmt.Println("User clicked Complete button")
case "CANCEL":
fmt.Println("User clicked Cancel button")
}
})