Package Reference
Project Setup
Tailwind CSS v4 setup (required)
The chat UI relies on Tailwind CSS v4 utility classes, so three CSS setup steps are required or the interface will render unstyled.
- Import Tailwind and the package stylesheet.
- Add @source entries so Tailwind scans the package's bundled class names.
- Define the --chat-theme* CSS custom properties in :root.
Vite — src/index.css
Place this in src/index.css (or your Vite entry CSS). The @source paths use a single ../ because the file sits one level below the project root.
@import "tailwindcss";
@import "@realtimexsco/live-chat/styles.css";
@source "../node_modules/@realtimexsco/live-chat/dist/index.mjs";
@source "../node_modules/@realtimexsco/live-chat/dist/index.cjs";
@source "../**/*.{js,jsx,ts,tsx}";
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
/* ... */
/* Overridden at runtime by ChatMain `themeColor` */
--chat-theme: #6366f1;
--chat-theme-5: #6366f10D;
--chat-theme-10: #6366f11A;
--chat-theme-20: #6366f133;
--chat-theme-40: #6366f166;
--chat-theme-60: #6366f199;
}
@theme inline {
--color-background: var(--background);
--color-chat-theme: var(--chat-theme);
/* ...map remaining --color-* tokens to their --variable counterparts */
}
@layer base {
html, body, #root { height: 100%; }
body { @apply bg-background text-foreground; }
}Next.js — src/app/globals.css
Same tokens and imports as Vite, but every @source path is one level deeper because globals.css lives in src/app/.
@import "tailwindcss";
@import "@realtimexsco/live-chat/styles.css";
@source "../../node_modules/@realtimexsco/live-chat/dist/index.mjs";
@source "../../node_modules/@realtimexsco/live-chat/dist/index.cjs";
@source "../../**/*.{js,jsx,ts,tsx}";
:root {
--radius: 0.625rem;
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
/* ... */
/* Overridden at runtime by ChatMain `themeColor` */
--chat-theme: #6366f1;
--chat-theme-5: #6366f10D;
--chat-theme-10: #6366f11A;
--chat-theme-20: #6366f133;
--chat-theme-40: #6366f166;
--chat-theme-60: #6366f199;
}
@theme inline {
--color-background: var(--background);
--color-chat-theme: var(--chat-theme);
/* ...map remaining --color-* tokens to their --variable counterparts */
}
@layer base {
html, body { height: 100%; }
body { @apply bg-background text-foreground; }
}@source path cheat sheet
| CSS file location | @source prefix |
|---|---|
| src/index.css (Vite) | ../node_modules/... |
| src/app/globals.css (Next.js) | ../../node_modules/... |
Vite — vite.config.ts
Deduplicate React and related peers so Vite does not load two copies of the same library (a common cause of invalid hook call errors). Exclude the chat package from optimizeDeps so upgrades pick up fresh builds without a stale prebundle.
import path from "path";
import { fileURLToPath } from "url";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: { "@": path.resolve(__dirname, "src") },
dedupe: [
"react",
"react-dom",
"zustand",
"socket.io-client",
"@realtimexsco/live-chat",
],
},
optimizeDeps: {
exclude: ["@realtimexsco/live-chat"],
include: ["zustand", "socket.io-client"],
},
});Next.js — next.config.ts
Add the package to transpilePackages so Next.js compiles its ESM correctly in both development and production builds.
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
transpilePackages: ["@realtimexsco/live-chat"],
};
export default nextConfig;Next.js — postcss.config.mjs
Next.js uses the Tailwind PostCSS plugin instead of the Vite plugin. Keep this file next to next.config.ts.
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;Environment variables
Environment variables are optional — they are simply a convenient way to keep credentials out of source control when building your chat.config.ts file.
Consuming them inside chat.config.ts:
# .env.local (Next.js) or .env (Vite, with VITE_ prefix)
NEXT_PUBLIC_CHAT_CLIENT_ID=your-client-id
NEXT_PUBLIC_API_V1_BASE_URL=https://example.com/api/v1
NEXT_PUBLIC_SOCKET_URL=https://example.comexport const chatConfig = {
clientId: process.env.NEXT_PUBLIC_CHAT_CLIENT_ID ?? "",
accessToken: "YOUR_JWT_ACCESS_TOKEN",
apiUrl: process.env.NEXT_PUBLIC_API_V1_BASE_URL ?? "",
socketUrl:
process.env.NEXT_PUBLIC_SOCKET_URL ??
(process.env.NEXT_PUBLIC_API_V1_BASE_URL ?? "").replace(/\/api\/v1\/?$/, ""),
};Required configuration file
Create src/configs/chat.config.ts to hold your credentials in one place:
function userIdFromToken(token: string): string | undefined {
try {
const payload = JSON.parse(
atob(token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")),
);
return payload._id || payload.id;
} catch {
return undefined;
}
}
const accessToken = "YOUR_JWT_ACCESS_TOKEN";
export const chatConfig = {
clientId: "YOUR_CLIENT_ID",
accessToken,
loggedUserDetails: {
_id: userIdFromToken(accessToken) ?? "YOUR_USER_ID",
name: "Your Name",
email: "you@example.com",
},
apiUrl: "https://example.com/api/v1",
socketUrl: "https://example.com", // optional
themeColor: "#6366f1",
} as const;