# Hide Channel History For Newly Added Members

This tutorial shows how to build a dialog that controls how much channel history a newly added member can see.

We will build the following simple dialog:

![Dialog for the past conversation history access restriction](@chat-sdk/react/v13/_assets/hide-channel-history-before-dialog.png)

### Minimal dialog to control history visibility when adding members

The UI below lets you choose how much of the conversation history a newly added member will see. On Add, it calls `channel.addMembers()` with `hide_history_before` mapped from the selected option:

- **don't include**: hide all history before now → `hide_history_before = new Date().toISOString()`
- **from today**: show only today → `hide_history_before = startOfToday.toISOString()`
- **from the beginning**: show everything → omit `hide_history_before`
- **custom**: show from a specific date/time → `hide_history_before = new Date(input).toISOString()`

## Best Practices

- Use absolute timestamps (`hide_history_before`) to avoid timezone surprises.
- Validate custom date input before calling `addMembers`.
- Default to the most privacy-preserving option for new members.
- Keep the dialog clear about what history will be visible.
- Consider server-side validation to prevent invalid values.

Minimal CSS was added to make it pleasant and centered.

<Tabs>

```tsx label="TSX"
import React, { useMemo, useState } from "react";
import { useChannelStateContext } from "stream-chat-react";
import "./add-members-dialog.css";

type HistoryMode = "none" | "today" | "all" | "custom";

type AddMembersDialogProps = {
  memberIds: string[];
};

export function AddMembersDialog({ memberIds }: AddMembersDialogProps) {
  const { channel } = useChannelStateContext();
  const [open, setOpen] = useState<boolean>(true);
  const [mode, setMode] = useState<HistoryMode>("none");
  const [customInput, setCustomInput] = useState<string>("");

  const isCustomDateValid = useMemo(() => {
    if (mode !== "custom") return true;
    const parsed = new Date(customInput);
    return !Number.isNaN(parsed.getTime());
  }, [mode, customInput]);

  const handleAdd = async () => {
    if (!channel) return;

    const options: { hide_history_before?: string } = {};

    if (mode !== "all") {
      let cutoff = new Date(); // do not show any history

      if (mode === "today") {
        const startOfToday = new Date();
        startOfToday.setHours(0, 0, 0, 0);
        cutoff = startOfToday;
      } else if (mode === "custom") {
        const parsed = new Date(customInput);
        if (Number.isNaN(parsed.getTime())) return;
        cutoff = parsed;
      }

      options.hide_history_before = cutoff.toISOString();
    }

    await channel.addMembers(memberIds, undefined, options);
    setOpen(false);
  };

  if (!open) return null;

  return (
    <div className="sch-dialog-overlay">
      <div className="sch-dialog">
        <h3 className="sch-title">Include conversation history?</h3>

        <div className="sch-options">
          <label className="sch-option">
            <input
              type="radio"
              name="history"
              value="none"
              checked={mode === "none"}
              onChange={() => setMode("none")}
            />
            <span>don't include</span>
          </label>

          <label className="sch-option">
            <input
              type="radio"
              name="history"
              value="today"
              checked={mode === "today"}
              onChange={() => setMode("today")}
            />
            <span>from today</span>
          </label>

          <label className="sch-option">
            <input
              type="radio"
              name="history"
              value="all"
              checked={mode === "all"}
              onChange={() => setMode("all")}
            />
            <span>from the beginning</span>
          </label>

          <label className="sch-option">
            <input
              type="radio"
              name="history"
              value="custom"
              checked={mode === "custom"}
              onChange={() => setMode("custom")}
            />
            <span>custom</span>
          </label>
        </div>

        {mode === "custom" ? (
          <div className="sch-custom">
            <input
              className="sch-input"
              type="datetime-local"
              value={customInput}
              onChange={(e) => setCustomInput(e.target.value)}
              placeholder="YYYY-MM-DDTHH:mm"
            />
            {!isCustomDateValid && (
              <div className="sch-error">Enter a valid date/time</div>
            )}
          </div>
        ) : null}

        <div className="sch-actions">
          <button
            className="sch-btn sch-secondary"
            onClick={() => setOpen(false)}
          >
            Cancel
          </button>
          <button
            className="sch-btn sch-primary"
            onClick={handleAdd}
            disabled={mode === "custom" && !isCustomDateValid}
          >
            Add
          </button>
        </div>
      </div>
    </div>
  );
}
```

```css label="CSS"
.sch-dialog-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);
  display: grid;
  place-items: center;
  padding: 16px;
  z-index: 1000;
}
.sch-dialog {
  width: 100%;
  max-width: 420px;
  background: #fff;
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
  padding: 16px 18px;
  font-family:
    ui-sans-serif,
    system-ui,
    -apple-system,
    Segoe UI,
    Roboto,
    Ubuntu,
    Cantarell,
    Noto Sans,
    sans-serif,
    Apple Color Emoji,
    Segoe UI Emoji;
}
.sch-title {
  margin: 4px 0 12px;
  font-size: 16px;
  font-weight: 600;
}
.sch-options {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
}
.sch-option {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
}
.sch-custom {
  margin: 8px 0 12px;
}
.sch-input {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 10px;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  font-size: 14px;
}
.sch-error {
  color: #b91c1c;
  font-size: 12px;
  margin-top: 6px;
}
.sch-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 4px;
}
.sch-btn {
  border: 0;
  border-radius: 8px;
  padding: 8px 12px;
  font-size: 14px;
  cursor: pointer;
}
.sch-primary {
  background: #005fff;
  color: #fff;
}
.sch-primary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.sch-secondary {
  background: #f3f4f6;
  color: #111827;
}
```

</Tabs>

### Mapping to the raw API

Here’s a standalone snippet showing the parameter shape. This mirrors the button behavior above:

```ts
// Example: include only the last 7 days of history for the new member
const cutoff = new Date();
cutoff.setDate(cutoff.getDate() - 7);
await channel.addMembers(["thierry"], undefined, {
  hide_history_before: cutoff.toISOString(),
});
```


---

This page was last updated at 2026-04-21T09:53:42.279Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v13/guides/customization/hide-channel-history-for-new-members/](https://getstream.io/chat/docs/sdk/react/v13/guides/customization/hide-channel-history-for-new-members/).