coxwave-sdk
v1.0.14
Published
A vanilla JS SDK
Readme
ax-sdk-chatbot
version: 1.1.0
📚 Table of Contents
installation
npm
npm i ax-sdk-chatbotyarn
yarn add ax-sdk-chatbotQuick Use
vite
Use In Root
-main.tsx;
import { createRoot } from "react-dom/client";
import CoxwaveChatSDK from "ax-sdk-chatbot";
import App from "./App.tsx";
import "./index.css";
const sdk = new CoxwaveChatSdk({
hostClientUrl: import.meta.env.VITE_CLIENT_URL, // your client url (if you use localhost, your client url is http://localhost:5173)
pluginKey: import.meta.env.VITE_FIRSTBRAIN_PLUGIN_KEY,
isProd: false,
});
createRoot(document.getElementById("root")!).render(<App />);
sdk.initChat({
chatApiParams: {
userId: "user_id",
courseId: "course_id",
courseName: "course_name",
courseCategory: "course_category",
courseSubCategory: "course_sub_category",
clipId: "clip_id",
clipPlayHead: clip_play_head_number,
},
shortcutKey: {
openChat: { key: "/", modifier: "" },
sendChat: { key: "Enter", modifier: "" },
},
customStyles: {
floatingButton: {
isInElement: true,
parentElementId: "root-button", // <------ here is your Floating Button parent element Id
},
},
});
-App.tsx;
import { useEffect, useState } from "react";
import "./App.css";
import CoxwaveChatSdk from "coxwave-sdk";
function App({ sdk }: { sdk: CoxwaveChatSdk }) {
const [clipPlayHead, setClipPlayHead] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setClipPlayHead((prev) => prev + 5);
}, 1000);
return () => clearInterval(interval);
}, []);
useEffect(() => {
sdk.postChatInfo({
clipId: "58767",
clipPlayHead,
});
}, [clipPlayHead]);
return (
<>
<div id="root-button">{Your Floating Button styles Element}</div> // <------ This is your floating button parent element. It must have the same ID as parentElementId.
</>
);
}
export default App;Use Custom Hook (with useEffect)
- Test.tsx (can use any component)
import { useEffect, useState } from "react";
import CoxwaveChatSDK from "ax-sdk-chatbot";
import BotImage from "./assets/quick-menu.png";
const sdk = new CoxwaveChatSDK({
hostClientUrl: import.meta.env.VITE_CLIENT_URL,
pluginKey: import.meta.env.VITE_FIRSTBRAIN_PLUGIN_KEY,
isProd: import.meta.env.VITE_IS_PROD === "true",
});
function Test() {
const [clipPlayHead, setClipPlayHead] = useState(0);
useEffect(() => {
sdk.initChat({
chatApiParams: {
userId: "user_id",
courseId: "course_id",
courseName: "course_name",
courseCategory: "course_category",
courseSubCategory: "course_sub_category",
clipId: "clip_id",
clipPlayHead: clip_play_head_number,
},
customStyles: {
floatingButton: {
isInElement: true,
parentElementId: "root-button",
},
},
});
return () => {
sdk.removeChat(); // this is sdk cleanup function
};
}, []);
useEffect(() => {
const interval = setInterval(() => {
setClipPlayHead((prev) => prev + 5);
}, 1000);
return () => clearInterval(interval);
}, []);
useEffect(() => {
sdk.postChatInfo({
clipId: "58767",
clipPlayHead,
});
}, [clipPlayHead]);
return (
<S.LayoutContainer $isWhiteBack={true}>
<S.ContentBox>
<S.RootButton id="root-button">
<S.BotImage src={BotImage} />
<S.Text>AI 튜터</S.Text>
</S.RootButton>
</S.ContentBox>
</S.LayoutContainer>
);
}
export default Test;
const S = {
~
} // your styles (this example is for styled-components)
Next.js
- page.tsx
import Sdk from "./Sdk";
export default function Home() {
return (
<Sdk />
);
}
- Sdk.tsx
"use client"; // if you use this sdk in Next.js, you must use this
import { useEffect, useRef } from "react";
import CoxwaveChatSdk from "ax-sdk-chatbot";
const clientUrl = process.env.NEXT_PUBLIC_HOST_CLIENT_URL; // your client url (if you use localhost, your client url is http://localhost:3000)
const pluginKey = process.env.NEXT_PUBLIC_COXWAVE_PLUGIN_KEY;
if (!clientUrl) {
throw new Error("NEXT_PUBLIC_COXWAVE_CLIENT_URL is not set");
}
if (!pluginKey) {
throw new Error("NEXT_PUBLIC_COXWAVE_PLUGIN_KEY is not set");
}
function Sdk() {
const iframeRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!clientUrl || !pluginKey) return;
const coxwaveChatSdkInstance = new CoxwaveChatSdk({
hostClientUrl: clientUrl,
pluginKey: pluginKey,
});
const init = async () => {
try {
await coxwaveChatSdkInstance.initChat({
chatApiParams: {
userId: "user_id",
courseId: "course_id",
courseName: "course_name",
courseCategory: "course_category",
courseSubCategory: "course_sub_category",
clipId: "clip_id",
clipPlayHead: clip_play_head_number,
},
customStyles: {
floatingButton: {
isInElement: true,
parentElementId: "root-button", // <------ here is your Floating Button parent element Id
},
},
});
} catch (err) {
console.error("SDK initChat 실패:", err);
}
};
init(); // 즉시 실행
return () => {
coxwaveChatSdkInstance.removeChat();
};
}, [clientUrl]);
return (
<div
ref={iframeRef}
id="root-button" // <------ This is your floating button parent element. It must have the same ID as parentElementId.
style={{
width: "50px",
height: "50px",
backgroundColor: "red",
cursor: "pointer",
}}
>
<button>Open Chat</button>
</div>
);
}
export default Sdk;Types
SDK Class
const coxwaveChatSDKInstance = new CoxwaveChatSDK({
hostClientUrl: "~",
pluginKey: "~",
});
type CoxwaveChatSDKType = {
hostClientUrl: string;
pluginKey: string;
isProd?: boolean;
};initChat Method
async initChat({
chatApiParams,
customStyles,
shortcutKey,
}: {
chatApiParams: ChatApiParamsType;
customStyles?: CustomStylesType;
shortcutKey?: ShortcutKeyType;
})
type ChatApiParamsType = {
userId: string;
courseId: string;
courseName: string;
courseCategory: string;
courseSubCategory: string;
clipId: string | null;
clipPlayHead: number | null;
};
type CustomStylesType = {
floatingButton?: FloatingButtonType;
chatBody?: ChatBodyType;
};
type ShortcutKeyType = {
openChat: ShortcutKeyPropertiesType;
sendChat: ShortcutKeyPropertiesType;
};
type FloatingButtonType = {
isInElement?: boolean;
parentElementId?: string;
style?: Partial<CSSStyleDeclaration>;
};
type ChatBodyType = {
position?: PositionType;
width?: string;
height?: string;
};
type PositionType = {
top?: string;
left?: string;
right?: string;
bottom?: string;
};
type ShortcutKeyPropertiesType = {
key: string;
modifier: "ctrlKey" | "altKey" | "shiftKey" | "metaKey" | "";
};
postChatInfo Method
postChatInfo({
clipId,
clipPlayHead,
}: {
clipId: string;
clipPlayHead: number;
})- you must use postChatInfo method after initChat method
removeChat Method
removeChat();legacy
Ver 0.x.x: https://www.npmjs.com/package/ax-sdk-chatbot/v/0.3.7
license
Copyright (c) 2025-present, Coxwave
