React SDK
@cstar.help/react provides React hooks for fetching and mutating cStar data. Built on top
of the core JS client with automatic loading states and error handling.
Installation
npm install @cstar.help/react
This automatically installs @cstar.help/js (the core client) as a dependency. Requires
React 18+.
CStarProvider
Wrap your app with the provider to make the client available to all hooks.
app/providers.tsx
import { CStarProvider } from '@cstar.help/react';
export default function Providers({ children }) {
return (
<CStarProvider apiKey={process.env.NEXT_PUBLIC_CSTAR_KEY}>
{children}
</CStarProvider>
);
}
Hooks
useTickets
import { useTickets } from '@cstar.help/react';
function TicketList() {
const {
tickets, // Ticket[]
loading, // boolean
error, // CStarError | null
pagination, // { page, pageSize, total, totalPages }
refetch // () => Promise<void>
} = useTickets({ status: 'open', priority: 'high' });
if (loading) return <Spinner />;
if (error) return <ErrorMessage error={error} />;
return (
<>
<p>{pagination.total} tickets found</p>
{tickets.map(t => <TicketRow key={t.id} ticket={t} />)}
</>
);
}
useTicket
import { useTicket } from '@cstar.help/react';
function TicketDetail({ ticketId }) {
const { ticket, loading } = useTicket(ticketId);
if (loading) return <Spinner />;
return (
<div>
<h2>{ticket.title}</h2>
<p>Status: {ticket.status}</p>
{ticket.messages?.map(msg => (
<Message key={msg.id} message={msg} />
))}
</div>
);
}
useCustomers
import { useCustomers } from '@cstar.help/react';
function CustomerList() {
const { customers, loading } = useCustomers({
status: 'active',
search: 'enterprise'
});
// ...
}
useArticles
import { useArticles } from '@cstar.help/react';
function KnowledgeBase() {
const { articles, loading } = useArticles({
status: 'published',
isPublic: true
});
// ...
}
Mutations
Use the client directly for create, update, and delete operations.
import { useCStarClient } from '@cstar.help/react';
function CreateTicketButton() {
const cstar = useCStarClient();
const [loading, setLoading] = useState(false);
async function handleCreate() {
setLoading(true);
try {
const ticket = await cstar.tickets.create({
title: 'New ticket from React',
priority: 'normal'
});
console.log('Created:', ticket.id);
} finally {
setLoading(false);
}
}
return (
<button onClick={handleCreate} disabled={loading}>
{loading ? 'Creating...' : 'Create Ticket'}
</button>
);
}
Real-Time Subscriptions
import { useSubscription } from '@cstar.help/react';
function TicketNotifications() {
useSubscription('ticket.created', (event) => {
toast(`New ticket: ${event.data.title}`);
});
useSubscription('ticket.closed', (event) => {
toast(`Ticket resolved: ${event.data.title}`);
});
return null; // This hook just listens
}