# Message Reminders

Message reminders let users set follow-up notifications for specific messages. The React SDK handles the UI and state, while the low-level JS client handles the underlying CRUD operations. For API details, see the low-level client guide. [The low-level client guide](/chat/docs/javascript/message_reminders/)

## Best Practices

- Keep reminder actions in the message menu for discoverability.
- Use `useMessageReminder` state for live countdowns instead of custom timers.
- Keep reminder offsets small and meaningful for your product.
- Avoid frequent UI refreshes beyond the default timer boundaries.
- Provide clear feedback when reminders are created or removed.

## Message Reminder UI Interaction

Users can create, update, or delete reminders from the message actions menu. When a reminder exists, the Message UI component shows a reminder notification; removing the reminder removes the notification.

## Get Message Reminder Data

The React SDK uses `client.reminders` to perform CRUD operations. The controller maintains reactive state: a map of message IDs to `Reminder` instances. Each `Reminder` has its own reactive state that extends the server `ReminderResponse` with `timeLeftMs`.

```ts
export type ReminderState = {
  channel_cid: string;
  created_at: Date;
  message: MessageResponse | null;
  message_id: string;
  remind_at: Date | null;
  timeLeftMs: number | null;
  updated_at: Date;
  user: UserResponse | null;
  user_id: string;
};
```

You can subscribe at two levels:

1. Subscribe to a specific reminder’s state

```tsx
import { useMessageReminder, useStateStore } from "stream-chat-react";
import type { LocalMessage, ReminderState } from "stream-chat";

const reminderStateSelector = (state: ReminderState) => ({
  timeLeftMs: state.timeLeftMs,
});

const Component = ({ message }: { message: LocalMessage }) => {
  // access the message reminder instance
  const reminder = useMessageReminder(message.id);
  const { timeLeftMs } =
    useStateStore(reminder?.state, reminderStateSelector) ?? {};
};
```

`timeLeftMs` updates periodically. The closer the deadline, the more frequent the updates (daily → hourly → minutely), and the reverse as you move away from the deadline.

2. Subscribe to reminders pagination

Pagination is handled by `RemindersPaginator`. The items are `ReminderResponse` objects from the server, not `Reminder` instances.

```tsx
import {
  InfiniteScrollPaginator,
  useChatContext,
  useStateStore,
} from "stream-chat-react";
import type { PaginatorState, ReminderResponse } from "stream-chat";
import { CustomLoadingIndicator } from "../LoadingIndicator";
import { CustomReminderListingItem } from "./CustomReminderListingItem";

const reminderPaginatorStateSelector = (
  state: PaginatorState<ReminderResponse>,
) => ({
  isLoading: state.isLoading,
  items: state.items,
});

const Component = () => {
  const { client } = useChatContext();
  const { items, isLoading } = useStateStore(
    client.reminders.paginator.state,
    reminderPaginatorStateSelector,
  );

  return (
    <InfiniteScrollPaginator
      loadNextOnScrollToBottom={client.reminders.queryNextReminders}
      threshold={40}
    >
      {items && (
        <div>
          {items.map((item) => (
            <CustomReminderListingItem reminder={item} key={item.message_id} />
          ))}
        </div>
      )}
      {isLoading && <CustomLoadingIndicator />}
    </InfiniteScrollPaginator>
  );
};
```

## Message Reminder Configuration

You can configure the reminder offsets users can pick from:

```js
const minute = 60 * 1000;
client.reminders.updateConfig({
  scheduledOffsetsMs: [30 * minute, 60 * minute],
});
```

You can also set the boundary for when the reminder notification stops refreshing elapsed time:

```js
const day = 24 * 60 * 60 * 1000;
client.reminders.updateConfig({
  stopTimerRefreshBoundaryMs: day,
});
```

## Overriding Default Message Reminder Components

You can override the reminder components in the React SDK:

```tsx
import {
  Channel,
  ReminderNotificationProps,
  useMessageReminder,
  useStateStore,
} from 'stream-chat-react';
import type { LocalMessage, ReminderState } from 'stream-chat';

const reminderStateSelector = (state: ReminderState) => ({
  timeLeftMs: state.timeLeftMs,
});

const CustomReminderNotification = ({ reminder }: ReminderNotificationProps) => {
  const { timeLeftMs } =
    useStateStore(reminder?.state, reminderStateSelector) ?? {};

  return (
    // ... the reminder notification UI component
  );
};

const Component = () => {
  return (
    <Channel ReminderNotification={CustomReminderNotification}>
      {/* ... */}
    </Channel>
  );
};
```


---

This page was last updated at 2026-04-21T07:55:45.661Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v13/guides/message-reminders/](https://getstream.io/chat/docs/sdk/react/v13/guides/message-reminders/).