# Custom Member Roles

This cookbook shows how to customize the role badges rendered next to each member in the [`ChannelDetails` component](/chat/docs/sdk/react-native/ui-components/channel-details/).

Roles are driven by a single `getMemberRoles` callback. It receives the default roles the SDK computed for a member (`defaultRoleLabels`) plus the `channel`, `member`, and `t` (translation) helpers, and returns the final list of `{ key, label }` roles to render. With it you can **extend** the defaults (add your own role, for example VIP) or **overwrite** them entirely (return a list you build from scratch). The default implementation marks members as `owner` (channel creator), `admin` (`user.role === 'admin'`) and `moderator` (`channel_role === 'channel_moderator'`).

Each role is then rendered by the overridable `RoleItem` badge, so you can also restyle a specific role — for example, give a VIP badge a yellow label.

`getMemberRoles` is a prop on `ChannelMemberItem`, and the parent lists don't forward it for you. To apply it, override `ChannelMemberItem` through `WithComponents` and pass your callback — a single override covers both the member preview on the details screen and the full members list.

## Best Practices

- Spread `defaultRoleLabels` when extending so members keep their built-in roles (and any roles added in future SDK versions) instead of rebuilding the list from scratch.
- Return an empty array to render no roles for a member.
- `getMemberRoles` isn't forwarded by the parent lists — override `ChannelMemberItem` with `WithComponents` and pass it. One override applies everywhere members are listed.
- `RoleItem` is the overridable badge. Reuse it and pass `viewStyle` / `textStyle` for light styling, or render your own view for total control.
- The `channelDetails.roleItem` theme keys only distinguish owner vs non-owner badges globally — to color a specific role like VIP, override `RoleItem` and branch on `role.key`.

## Extending the Default Roles

To add a role on top of the built-in ones, keep `defaultRoleLabels` and append your own entry. Here we add a **VIP** badge for members flagged as VIP (a custom user field on user):

```tsx
import { GetMemberRoles } from "stream-chat-react-native";

const getMemberRoles: GetMemberRoles = ({ defaultRoleLabels, member }) => {
  if (member.user?.custom.vip) {
    return [...defaultRoleLabels, { key: "vip", label: "VIP" }];
  }
  return defaultRoleLabels;
};
```

`getMemberRoles` lives on `ChannelMemberItem`, so wire it by overriding that component through `WithComponents` and forwarding the props the SDK passes in. Everything must live inside the `ChannelDetailsContextProvider`:

```tsx
import {
  ChannelDetails,
  ChannelDetailsContextProvider,
  ChannelMemberItem,
  ChannelMemberItemProps,
  WithComponents,
} from "stream-chat-react-native";

const MemberItem = (props: ChannelMemberItemProps) => (
  <ChannelMemberItem {...props} getMemberRoles={getMemberRoles} />
);

const ChannelDetailsScreen = ({ route, navigation }) => {
  const { channel } = route.params;
  return (
    <ChannelDetailsContextProvider channel={channel}>
      <WithComponents overrides={{ ChannelMemberItem: MemberItem }}>
        <ChannelDetails onBack={() => navigation.goBack()} />
      </WithComponents>
    </ChannelDetailsContextProvider>
  );
};
```

A **VIP** badge now appears next to every member your `getMemberRoles` flags, in addition to their built-in Owner / Admin / Moderator roles.

| Default roles                                                                                                            | With VIP badge                                                                                                          |
| ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| ![Default roles](@chat-sdk/react-native/v9-latest/_assets/ui-cookbook/channel-details/channel-details-roles-initial.PNG) | ![With VIP badge](@chat-sdk/react-native/v9-latest/_assets/ui-cookbook/channel-details/channel-details-custom-role.PNG) |

## Overriding the Default Roles

To take full control, ignore `defaultRoleLabels` and build the list yourself. Here we drop the built-in rules entirely and only show an **Admin** badge for members whose role is your own `my_admin` role:

```tsx
import { GetMemberRoles, RoleLabel } from "stream-chat-react-native";

const getMemberRoles: GetMemberRoles = ({ member, t }) => {
  const roles: RoleLabel[] = [];

  if (member.user?.role === "my_admin") {
    roles.push({ key: "admin", label: t("Admin") });
  }

  return roles;
};
```

Wire it exactly as before — override `ChannelMemberItem` with `WithComponents` and pass this `getMemberRoles`. Members without the `my_admin` role now render no badges at all.

## Styling the Roles

Each badge is rendered by the overridable `RoleItem` component, which receives `RoleItemProps` (`role`, plus optional `viewStyle` / `textStyle`). Override it through `WithComponents` to style a specific role. The `role.key` tells you which role you're rendering (`"owner"`, `"admin"`, `"moderator"`, or any custom key like `"vip"`).

The simplest approach is to reuse the default `RoleItem` and pass it `viewStyle` / `textStyle` — they layer over the badge's default (and themed) styles. Here we color the VIP badge yellow and delegate every other role to the default rendering:

```tsx
import { RoleItem, RoleItemProps } from "stream-chat-react-native";

const CustomRoleItem = (props: RoleItemProps) =>
  props.role.key === "vip" ? (
    <RoleItem
      {...props}
      textStyle={{ color: "#F5A623" }}
      viewStyle={{ backgroundColor: "#FFF8E1" }}
    />
  ) : (
    <RoleItem {...props} />
  );
```

Register the override through `WithComponents`, alongside the `ChannelDetailsContextProvider`:

```tsx
import {
  ChannelDetails,
  ChannelDetailsContextProvider,
  WithComponents,
} from "stream-chat-react-native";

const ChannelDetailsScreen = ({ route, navigation }) => {
  const { channel } = route.params;
  return (
    <ChannelDetailsContextProvider channel={channel}>
      <WithComponents
        overrides={{ ChannelMemberItem: MemberItem, RoleItem: CustomRoleItem }}
      >
        <ChannelDetails onBack={() => navigation.goBack()} />
      </WithComponents>
    </ChannelDetailsContextProvider>
  );
};
```

| Default VIP badge                                                                                                          | Styled VIP badge                                                                                                                     |
| -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| ![Default VIP badge](@chat-sdk/react-native/v9-latest/_assets/ui-cookbook/channel-details/channel-details-custom-role.PNG) | ![Styled VIP badge](@chat-sdk/react-native/v9-latest/_assets/ui-cookbook/channel-details/channel-details-custom-role-and-design.PNG) |


---

This page was last updated at 2026-06-30T12:00:26.465Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/guides/channel-details-custom-member-roles/](https://getstream.io/chat/docs/sdk/react-native/guides/channel-details-custom-member-roles/).