Basic usage
Mount the DMs list and listen for channel selection events to navigate users into a conversation.- React
- Vanilla JS
- Swift
"use client";
import { useCallback, useMemo, useState } from "react";
import {
ChatSession,
DmsListElement,
Elements,
} from "@whop/embedded-components-react-js";
import { loadWhopElements } from "@whop/embedded-components-vanilla-js";
import type {
DmsListElementEvent,
DmsListElementOptions,
} from "@whop/embedded-components-vanilla-js/types";
const elements = loadWhopElements();
async function getToken() {
const response = await fetch("/api/token");
const data = await response.json();
return data.token;
}
export function MessagesPage() {
const [channelId, setChannelId] = useState<string>();
const handleDmsEvent = useCallback((event: DmsListElementEvent) => {
switch (event.type) {
case "channelSelected":
setChannelId(event.detail.id);
break;
}
}, []);
const dmsOptions: DmsListElementOptions = useMemo(() => {
return {
selectedChannel: channelId,
onEvent: handleDmsEvent,
};
}, [channelId, handleDmsEvent]);
return (
<Elements elements={elements}>
<ChatSession token={getToken}>
<DmsListElement options={dmsOptions} />
</ChatSession>
</Elements>
);
}
import { loadWhopElements } from "@whop/embedded-components-vanilla-js";
async function getToken() {
const response = await fetch("/api/token");
const data = await response.json();
return data.token;
}
const whopElements = await loadWhopElements();
const session = whopElements.createChatSession({
token: getToken,
});
const dmsListElement = session.createElement("dms-list-element", {});
dmsListElement.on("channelSelected", (ev) => {
console.log("Channel selected:", ev.detail.id);
});
dmsListElement.mount("#dms-list-container");
struct MessagesView: View {
@State private var selectedChannel: DMChannel?
var body: some View {
WhopDMsListView(
onEvent: { event in
switch event {
case let .channelSelected(channel):
selectedChannel = channel
}
}
)
.navigationDestination(item: $selectedChannel) { channel in
WhopChatView(
channelId: channel.id,
style: .imessage
)
.navigationBarTitleDisplayMode(.inline)
.navigationTitle(channel.name)
}
}
}
Company scoping
Filter the DMs list to only show conversations belonging to a specific company by passing acompanyId. To programmatically create DMs, use the Create DM Channel endpoint — make sure to pass the same companyId so the DM appears in the scoped list.
- React
- Vanilla JS
- Swift
const dmsOptions: DmsListElementOptions = useMemo(() => {
return {
companyId: "biz_xxxx",
selectedChannel: channelId,
onEvent: handleDmsEvent,
};
}, [channelId, handleDmsEvent]);
return (
<Elements elements={elements}>
<ChatSession token={getToken}>
<DmsListElement options={dmsOptions} />
</ChatSession>
</Elements>
);
const dmsListElement = session.createElement("dms-list-element", {
companyId: "biz_xxxx",
});
dmsListElement.mount("#dms-list-container");
WhopDMsListView(
companyId: "biz_xxxx",
onEvent: { event in
switch event {
case let .channelSelected(channel):
selectedChannel = channel
}
}
)
Event handling
Listen for channel selection to open the corresponding chat view.- React
- Vanilla JS
- Swift
| Event | Detail | Description |
|---|---|---|
channelSelected | { id: string } | Emitted when the user clicks a channel |
const handleDmsEvent = useCallback((event: DmsListElementEvent) => {
switch (event.type) {
case "channelSelected":
setChannelId(event.detail.id);
break;
}
}, []);
| Event | Detail | Description |
|---|---|---|
channelSelected | { id: string } | Emitted when the user clicks a channel |
dmsListElement.on("channelSelected", (ev) => {
console.log("Channel selected:", ev.detail.id);
});
| Event | Detail | Description |
|---|---|---|
.channelSelected | channel: DMChannel | Emitted when the user taps a channel |
WhopDMsListView(
onEvent: { event in
switch event {
case let .channelSelected(channel):
selectedChannel = channel
}
}
)
.navigationDestination(item: $selectedChannel) { channel in
WhopChatView(
channelId: channel.id,
style: .imessage
)
.navigationBarTitleDisplayMode(.inline)
.navigationTitle(channel.name)
}

