Skip to content
Ink
Esc
↑↓navigate↵open⌘Jpreview
On this page

Notifications

Local reminders and routes back into the app.

Use @ink/notifications to show a notification or schedule a local reminder. Tapping it can open a screen in your app.

Permissions

Permission Required for
notifications Showing notifications and scheduling reminders.
Exact alarm access Reminders with exact: true, in addition to notification access.
import { lightos } from "@ink/lightos";

const permission = await lightos.requestPermission("notifications");

Use lightos.getPermission("notifications") to check without a prompt. See Request a permission for the returned statuses.

Exact reminders

Android requires separate access to schedule reminders at an exact time:

if (!await lightos.canScheduleExact()) {
  await lightos.requestExactPermission();
}

requestExactPermission() returns after opening settings; it does not wait for a decision. When the user returns to the app, check again before scheduling:

const allowed = await lightos.canScheduleExact();

Only schedule with exact: true when allowed is true.

Show a notification

import { notifications } from "@ink/notifications";

await notifications.show({
  id: `download-${downloadId}`,
  title: "Download complete",
  body: "Your episode is ready offline",
  href: "/downloads",
  data: JSON.stringify({ downloadId }),
});

Reuse an id to update or replace a notification. href names a registered screen; data is a string.

Schedule a reminder

Schedule a reminder for ten minutes from now:

import { notifications } from "@ink/notifications";

await notifications.schedule({
  id: "tea",
  at: Date.now() + 10 * 60 * 1_000,
  title: "Tea is ready",
  body: "Your timer has finished",
});

at is a timestamp in milliseconds. Delivery time is approximate by default. exact: true requires exact-alarm access; without it, scheduling fails.

Cancel a reminder

await notifications.cancel("tea");

Handle notification taps

useNotificationTap() provides the tapped ID and data. Call consume() to clear the tap. Validate the data and load saved records when a notification starts the app.

Pass screen parameters

For an app with a /departures screen:

await notifications.show({
  id: "departure-station-7",
  title: "Bus arriving",
  body: "Your bus arrives in five minutes",
  href: { path: "/departures", params: { stopId: "station-7" } },
});

Read parameters with useRouteParams() after a tap, including when the app starts from closed.

Parameters must be JSON values totalling at most 8 KiB. The complete notification request is limited to 12 KiB. data is a separate string payload.

Handle duplicate taps and records that have since been deleted. Update reminders when events or time zones change.

Push notifications

Use LightOS for host push integration. Validate incoming account and record IDs, update your app’s data, then decide whether to show a notification.

Private content

Notification content can be visible outside the app. Offer limited previews for private messages. LightOS may restrict how notifications and actions appear.