React / Next.js
Setup Ticketping chat widget in React or Next.js projects
Quick Start
The easiest way to use the Ticketping Chat Widget in React/Next.js:
npm install @ticketping/chat-widget
import React, { useRef } from 'react';
import TicketpingChat from '@ticketping/chat-widget/react';
function App() {
const chatRef = useRef();
return (
<div>
<h1>My App</h1>
<TicketpingChat
ref={chatRef}
appId="your-app-id"
teamSlug="your-team-slug"
teamLogoIcon="cdn-link-to-your-logo-square"
/>
</div>
);
}
export default App;
With Custom Theme
import React, { useRef } from 'react';
import TicketpingChat from '@ticketping/chat-widget/react';
const myTheme = {
primaryColor: '#007BFF', // accent color
primaryHover: '#0056b3', // slightly darker accent color
textPrimary: '#111827', // gray.900 (main text)
textSecondary: '#374151', // gray.700 (secondary text)
textMuted: '#6b7280', // gray.500 (muted text)
background: '#ffffff', // white
backgroundSecondary: '#f3f4f6', // gray.100
backgroundTertiary: '#e5e7eb', // gray.200
}
function App() {
const chatRef = useRef();
return (
<div>
<h1>My App</h1>
<TicketpingChat
ref={chatRef}
appId="your-app-id"
teamSlug="your-team-slug"
teamLogoIcon="cdn-link-to-your-logo-square"
theme={myTheme}
/>
</div>
);
}
export default App;
Want the chat widget to recognize your users? Check out our authentication guide.
Troubleshooting
If you get module resolution errors, try one of these solutions:
Update your tsconfig.json
{
"compilerOptions": {
"moduleResolution": "node16" // or "bundler"
}
}
Your own React component
If the module resolution still doesn't work, you can write your own component like this for better control.
import { useEffect, useRef } from 'react'
interface TicketpingWidgetProps {
appId?: string
teamSlug?: string
teamLogoIcon?: string
userJWT?: string
}
const myTheme = {
primaryColor: '#007BFF', // accent color
primaryHover: '#0056b3', // slightly darker accent color
textPrimary: '#111827', // gray.900 (main text)
textSecondary: '#374151', // gray.700 (secondary text)
textMuted: '#6b7280', // gray.500 (muted text)
background: '#ffffff', // white
backgroundSecondary: '#f3f4f6', // gray.100
backgroundTertiary: '#e5e7eb', // gray.200
}
const TicketpingWidget: React.FC<TicketpingWidgetProps> = ({
appId="your-app-id"
teamSlug="your-team-slug"
teamLogoIcon="cdn-link-to-your-logo-square"
userJWT,
}) => {
const widgetRef = useRef<any>(null)
const widgetReadyRef = useRef(false)
useEffect(() => {
if (typeof window === 'undefined') return
const loadWidget = async () => {
try {
// Dynamic import of the widget package
await import('@ticketping/chat-widget')
// @ts-ignore
await import('@ticketping/chat-widget/style')
// Configuration object
const config = {
appId,
teamSlug,
teamLogoIcon,
userJWT,
theme: lcsTheme,
}
// Initialize the widget
widgetRef.current = window.TicketpingChat.init(config)
} catch (error) {
console.error('Failed to load Ticketping Chat Widget:', error)
onError?.(error)
}
}
loadWidget()
// Cleanup on unmount
return () => {
if (widgetRef.current) {
widgetRef.current.destroy()
widgetRef.current = null
widgetReadyRef.current = false
}
}
}, []) // Only run once on mount
return null // Widget renders itself into DOM
}
export default TicketpingWidget