Basic usage
Pass achannelId to connect to a specific channel, DM, or support chat.
- React
- Vanilla JS
- Swift
"use client";
import { useMemo } from "react";
import {
ChatElement,
ChatSession,
Elements,
} from "@whop/embedded-components-react-js";
import { loadWhopElements } from "@whop/embedded-components-vanilla-js";
import type { ChatElementOptions } 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 ChatPage() {
const chatOptions: ChatElementOptions = useMemo(() => {
return {
channelId: "chat_feed_XXXXXXXXXXXXXX",
};
}, []);
return (
<Elements elements={elements}>
<ChatSession token={getToken}>
<ChatElement
options={chatOptions}
style={{ height: "100dvh", width: "100%" }}
/>
</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 chatElement = session.createElement("chat-element", {
channelId: "chat_feed_XXXXXXXXXXXXXX",
});
chatElement.mount("#chat-container");
import SwiftUI
import WhopElements
struct ChatView: View {
var body: some View {
WhopChatView(
channelId: "chat_feed_XXXXXXXXXXXXXX",
style: .imessage
)
}
}
Deeplinking to messages
To scroll to and highlight a specific message, passdeeplinkToPostId. The view will automatically navigate to that message.
- React
- Vanilla JS
- Swift
const chatOptions: ChatElementOptions = useMemo(() => {
return {
channelId: "chat_feed_XXXXXXXXXXXXXX",
deeplinkToPostId: "post_XXXXXXXXXXXXXX",
};
}, []);
<ChatElement options={chatOptions} />;
const chatElement = session.createElement("chat-element", {
channelId: "chat_feed_XXXXXXXXXXXXXX",
deeplinkToPostId: "post_XXXXXXXXXXXXXX",
});
chatElement.mount("#chat-container");
struct ChatView: View {
@State private var targetPostId: String? = nil
var body: some View {
WhopChatView(
channelId: "chat_feed_XXXXXXXXXXXXXX",
deeplinkToPostId: targetPostId,
style: .imessage
)
}
}
Event handling
Listen to user interactions like profile clicks, link clicks, and sent messages using the event callback for your platform.- React
- Vanilla JS
- Swift
| Event | Detail | Description |
|---|---|---|
profileClick | { id: string } | Emitted when the user clicks on a profile |
linkClick | { url: string } | Emitted when the user clicks on a link |
messageSent | { id: string, content: string, channelId: string } | Emitted when the user sends a message |
experienceClick | { id: string } | Emitted when the user clicks on an experience mention |
import { useCallback, useMemo } from "react";
import type {
ChatElementEvent,
ChatElementOptions,
} from "@whop/embedded-components-vanilla-js/types";
const handleChatEvent = useCallback((event: ChatElementEvent) => {
switch (event.type) {
case "profileClick":
console.log("Profile clicked:", event.detail.id);
break;
case "linkClick":
console.log("Link clicked:", event.detail.url);
break;
case "messageSent":
console.log("Message sent:", event.detail.id, event.detail.content, event.detail.channelId);
break;
case "experienceClick":
console.log("Experience clicked:", event.detail.id);
break;
}
}, []);
const chatOptions: ChatElementOptions = useMemo(() => {
return {
channelId: "chat_feed_XXXXXXXXXXXXXX",
onEvent: handleChatEvent,
};
}, [handleChatEvent]);
<ChatElement options={chatOptions} />;
| Event | Detail | Description |
|---|---|---|
profileClick | { id: string } | Emitted when the user clicks on a profile |
linkClick | { url: string } | Emitted when the user clicks on a link |
messageSent | { id: string, content: string, channelId: string } | Emitted when the user sends a message |
experienceClick | { id: string } | Emitted when the user clicks on an experience mention |
const chatElement = session.createElement("chat-element", {
channelId: "chat_feed_XXXXXXXXXXXXXX",
});
chatElement.on("profileClick", (ev) => {
console.log("Profile clicked:", ev.detail.id);
});
chatElement.on("linkClick", (ev) => {
console.log("Link clicked:", ev.detail.url);
});
chatElement.on("messageSent", (ev) => {
console.log("Message sent:", ev.detail.id, ev.detail.content, ev.detail.channelId);
});
chatElement.on("experienceClick", (ev) => {
console.log("Experience clicked:", ev.detail.id);
});
chatElement.mount("#chat-container");
| Event | Detail | Description |
|---|---|---|
.profileTap | username: String | Emitted when the user taps on a profile |
.urlTap | url: String | Emitted when the user taps on a link |
.messageSent | content: String, messageId: String | Emitted when the user sends a message |
WhopChatView(
channelId: "chat_feed_XXXXXXXXXXXXXX",
style: .imessage,
onEvent: { event in
switch event {
case let .profileTap(username):
print("Profile tapped: \(username)")
case let .urlTap(url):
print("URL tapped: \(url)")
case let .messageSent(content, messageId):
print("Message sent: \(messageId) - \(content)")
}
}
)

