# Blocking Users

## Introduction

Blocking is a user-safety feature that lets people stop direct messages from specific users. It does not remove those users from shared channels, so their messages can still appear in group chats.

## Best Practices

- Communicate clearly that blocking affects DMs, not shared channels.
- Require explicit user confirmation before blocking.
- Handle errors gracefully and provide user feedback.
- Keep block/unblock actions accessible in moderation UIs.
- Ensure `connectUser` is established before calling block APIs.

## Stream Chat

The Stream Chat SDK lets you block, unblock, and list blocked users. The client API is available after you connect a user.

## Low Level Client Support

The low-level client exposes the block APIs directly.

### Blocking a User

Use `client.blockUser` with the target user ID.

```tsx
import { StreamChat } from "stream-chat";
const client = StreamChat.getInstance("<API_KEY>");

const blockUser = async (userId: string) => {
  try {
    await client.blockUser(userId);
  } catch (error) {
    console.error("Error blocking user:", error);
  }
};
```

### Unblocking a User

Use `client.unBlockUser` with the target user ID.

```tsx
import { StreamChat } from "stream-chat";
const client = StreamChat.getInstance("<API_KEY>");

const unBlockUser = async (userId: string) => {
  try {
    await client.unBlockUser(userId);
  } catch (error) {
    console.error("Error unblocking user:", error);
  }
};
```

### Listing Blocked Users

Use `client.getBlockedUsers` and read the `blocks` array.

```tsx
const client = StreamChat.getInstance("<API_KEY>");

const getBlockedUsers = async () => {
  try {
    const users = await client.getBlockedUsers();
    setBlockedUsers(users.blocks);
  } catch (error) {
    console.error("Error getting blocked users:", error);
  }
};
```

<admonition type="note">

These APIs require an active client connection (`client.connectUser`).

</admonition>

## Message Actions

You can wire blocking into a custom dropdown action by extending [`MessageActions`](/chat/docs/sdk/react/guides/theming/actions/message-actions/) and registering it with `WithComponents`.

```tsx
import {
  type ContextMenuItemProps,
  Channel,
  MessageActions,
  WithComponents,
  defaultMessageActionSet,
  useContextMenuContext,
  useChatContext,
  useMessageContext,
} from "stream-chat-react";

const BlockUserAction = (props: ContextMenuItemProps) => {
  const { client } = useChatContext("BlockUserAction");
  const { message } = useMessageContext("BlockUserAction");
  const { closeMenu } = useContextMenuContext();

  if (!message.user_id) return null;

  return (
    <button
      {...props}
      className="str-chat__message-actions-list-item-button"
      onClick={async () => {
        await client.blockUser(message.user_id);
        closeMenu();
      }}
    >
      Block <strong>{message.user?.name ?? message.user?.id}</strong>
    </button>
  );
};

const CustomMessageActions = () => (
  <MessageActions
    messageActionSet={[
      ...defaultMessageActionSet,
      {
        Component: BlockUserAction,
        placement: "dropdown",
        type: "block-user",
      },
    ]}
  />
);

<WithComponents overrides={{ MessageActions: CustomMessageActions }}>
  <Channel>...</Channel>
</WithComponents>;
```

Starting from `defaultMessageActionSet` preserves the current dropdown trigger and the SDK's built-in action filtering. If you replace the action set completely, add your own `quick-dropdown-toggle` item when dropdown actions should still be reachable.


---

This page was last updated at 2026-07-16T09:38:26.583Z.

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