---
title: Interaction
description: Handle user interaction with the notification and quick actions.
---

Users can interact with notifications in a number of ways; via the Notification Center, when they display in
heads-up mode or via [Quick Actions](#quick-actions).

## Press Action

When a notification is displayed on the device, pressing it causes iOS to open the application. You can hook into the event to handle app-specific logic:

```js
import notifee, { EventType } from 'react-native-notify-kit';

notifee.onBackgroundEvent(async ({ type, detail }) => {
  if (type === EventType.PRESS) {
    console.log('User pressed the notification.', detail.pressAction.id);
  }
});
```

The `detail` provided with the event contains a `pressAction` with an `id` of `default`. Since there is no way to override the iOS behaviour for notification press, this is automatically set.

If your application has been freshly launched via a notification press, it will generate an [App open event](/react-native/events#app-open-events).

### Foreground vs background routing

PRESS events are routed to the handler that matches the app state at the moment of the tap:

- Foreground tap → `onForegroundEvent`
- Background / killed tap → `onBackgroundEvent`

On iOS the background-routing path relies on `UIApplication.applicationState` being read correctly at tap time. If you see background taps landing in `onForegroundEvent`, make sure you are on at least **v9.2.1** — earlier fork versions had a subtle bug (`dispatch_after` delay + wrong `UIApplicationStateBackground` check + off-main-thread state read) that caused the routing to always pick foreground. Events emitted in the ~1 second window between the iOS `Inactive` state and the app becoming `Active` can still be routed to the background handler intentionally; guard state-dependent handler logic with `AppState.currentState` if strict foreground delivery matters.

This background-routing behavior is what users in upstream [invertase/notifee#1155](https://github.com/invertase/notifee/issues/1155) experience — a tap from background lands in `onBackgroundEvent`, not `onForegroundEvent`. It is intentional and correct post-v9.2.1; register both handlers if you need to observe taps in every app state.

## Notification Delivery Events

On iOS, `EventType.DELIVERED` is emitted to `onForegroundEvent` whenever a Notify Kit-owned notification is presented to the user while the app is in foreground. This includes local `displayNotification` calls, trigger notifications that fire in foreground, and `handleFcmMessage` foreground displays. See the [behaviour guide](/react-native/ios/behaviour#foreground-delivery-events) for the iOS-specific caveats (background / killed trigger notifications do not emit DELIVERED on iOS).

## Quick Actions

Quick Actions are a way of making a notification more interactive, allowing users to perform quick actions directly from
the notification (e.g. within the devices Notification Center) and not open the application. For example, an incoming
message to a user displayed as a notification could have a "Mark as read" action, along with a "Reply" action which
lets the send a message.

<Vimeo id="402244609" caption="iOS Category Actions Example" />

At minimum, an action requires a unique identifier & text:

```js
async function setCategories() {
  await notifee.setNotificationCategories([
    {
      id: 'message',
      actions: [
        {
          id: 'mark-as-read',
          title: 'Mark as read',
        },
      ],
    },
  ]);
}
```

### Handling interaction

Whenever an user interacts with an action, an [event](/react-native/events) is sent to the device. The payload
contains the `id` within the `pressAction` property. For example, if the application is in the background and the user
presses a `mark-as-read` action, we can access it by listening to the `ACTION_PRESS` event:

```js
import notifee, { EventType } from 'react-native-notify-kit';

notifee.onBackgroundEvent(async ({ type, detail }) => {
  if (type === EventType.ACTION_PRESS && detail.pressAction.id === 'mark-as-read') {
    console.log('User pressed the "Mark as read" action.');
  }
});
```

### Foreground Action

The default behaviour when a user interacts with an action is to trigger an event via the `onBackgroundEvent` method
and remove the notification from the device (marking as read). You can however force the action to open the application
into the foreground by setting the `foreground` property to `true`:

```js
async function setCategories() {
  await notifee.setNotificationCategories([
    {
      id: 'message',
      actions: [
        {
          id: 'view-post',
          title: 'View post',
          // Trigger the app to open in the foreground
          foreground: true,
        },
      ],
    },
  ]);
}
```

Once pressed, the application will launch & send a `ACTION_PRESS` event.

### Destructive Action

The action can be further expanded to be a "destructive" one, or only show if the device is unlocked:

```js
async function setCategories() {
  await notifee.setNotificationCategories([
    {
      id: 'message',
      actions: [
        {
          id: 'view-post',
          title: 'View post',
          foreground: true,
        },
        {
          id: 'delete-chat',
          title: 'Delete chat',
          destructive: true,
          // Only show if device is unlocked
          authenticationRequired: true,
        },
      ],
    },
  ]);
}
```

The action will appear with red text, warning the user the action may have destructive intent.

<Vimeo id="402244498" caption="iOS Destructive Action" />

By default, a destructive action will not cause the application to open, however the `ACTION_PRESS` event will still be sent
regardless.

### Action input

Notify Kit also supports allowing users to provide custom user input via an action. To enable this functionality, set the
`input` property to `true`:

```js
async function setCategories() {
  await notifee.setNotificationCategories([
    {
      id: 'message',
      actions: [
        {
          id: 'reply',
          title: 'Reply',
          input: true,
        },
      ],
    },
  ]);
}
```

When the action is pressed, an input box and send button will automatically appear allowing for custom input:

<Vimeo id="402244554" caption="iOS Action Input" />

If required, the input box placeholder text and send button text can be customised by providing an object to the `input`
property:

```js
async function setCategories() {
  await notifee.setNotificationCategories([
    {
      id: 'message',
      actions: [
        {
          id: 'reply',
          title: 'Reply',
          input: {
            placeholderText: 'Send a message...',
            buttonText: 'Send Now',
          },
        },
      ],
    },
  ]);
}
```

#### Accessing input

In most cases you'll want to extract the users input and perform an action (e.g. send an API request to your servers).
Once the "Send" button is pressed, the `ACTION_PRESS` event triggers, sending the `pressAction` along with an
`input` property:

```js
import notifee, { EventType } from 'react-native-notify-kit';

notifee.onBackgroundEvent(async ({ type, detail }) => {
  const { notification, pressAction, input } = detail;

  if (type === EventType.ACTION_PRESS && pressAction.id === 'reply') {
    updateChatOnServer(notification.data.conversationId, input);
  }
});
```
