How-to guides
Handle notification taps
Own notification navigation in the app scope.
Mount the watcher
In the root component's mount effect, use useRouter() and the example imports:
const fiber = Effect.runFork(
Effect.scoped(
watchNotificationNavigation({ appId: config.appId, push: true })
).pipe(
Effect.provide(
Layer.mergeAll(
BridgeLive,
NotificationSnapshotsLive.pipe(Layer.provide(BridgeLive)),
tanstackStartAdapterLayer(router)
)
)
)
);
// Effect cleanup:
return () => {
Effect.runFork(Fiber.interrupt(fiber));
};Keep the watcher mounted across screen changes.
Set destinations
Use app-relative routes:
| Source | Field | Watcher option |
|---|---|---|
| Local | route | Omit push: true if local-only |
| Push | data.route | push: true |
| Offline | Mark route offline; visit exact URL after worker activation | Match query strings |
Verify taps
Test invalid routes, online taps, and offline taps to visited URLs.
You see valid destinations open; invalid routes are ignored.
flowchart TD
Local[LocalNotifications action] --> Queue[App-scoped watcher queue]
Push[FirebaseMessaging action when push: true] --> Queue
Browser[radical-notification browser event] --> Queue
Queue --> Valid{actionId is tap and route is valid?}
Valid -->|No| Ignore[Ignore event]
Valid -->|Yes| Network{getNetworkStatus}
Network -->|Connected| Router[Adapter navigation.navigate]
Network -->|Disconnected or status failure| Cache{Exact URL in app snapshot cache?}
Cache -->|Yes| Document[location.assign: full document navigation]
Cache -->|No or restore error| Router
Router -->|Failure| Error[onError callback; watcher continues]