Svelte Quickstart
Build a cStar integration with Svelte in under 5 minutes. This guide covers installation, seeding sample data, provider setup, knowledge base browsing, customer chat, and article search.
1. Install
npm install @cstar.help/svelte2. Seed Sample Data
If you haven't already, populate your team with sample help center content so you have data to work with:
cstar seedThis creates 5 categories, 12 articles, 3 customers, and 5 tickets. See the quickstart for details.
3. Set Up Providers
+layout.svelte
<!-- src/routes/+layout.svelte -->
<script>
import { CStarChatProvider, CStarLibraryProvider } from '@cstar.help/svelte';
let { children } = $props();
</script>
<!-- Two providers: Chat (authenticated) and Library (public) -->
<CStarLibraryProvider teamSlug="acme">
<CStarChatProvider
teamSlug="acme"
supabaseUrl={import.meta.env.VITE_SUPABASE_URL}
supabaseAnonKey={import.meta.env.VITE_SUPABASE_ANON_KEY}
>
{@render children()}
</CStarChatProvider>
</CStarLibraryProvider>4. Browse the Knowledge Base
List categories and articles from your public help center.
+page.svelte
<!-- src/routes/help/+page.svelte -->
<script>
import { getLibraryClient, CategoriesState, ArticlesState } from '@cstar.help/svelte';
const client = getLibraryClient();
const cats = new CategoriesState(client);
const articles = new ArticlesState(client, { limit: 5 });
</script>
<h2>Help Center</h2>
{#if cats.isLoading}
<p>Loading...</p>
{:else}
{#each cats.categories as cat (cat.id)}
<div>
<h3>{cat.name} ({cat.article_count})</h3>
</div>
{/each}
{/if}
<h2>Latest Articles</h2>
{#each articles.articles as a (a.id)}
<a href="/help/{a.slug}">{a.title}</a>
{/each}5. Add Customer Chat
Let customers start conversations and send messages in real-time.
ChatWidget.svelte
<!-- src/lib/components/ChatWidget.svelte -->
<script>
import { onDestroy } from 'svelte';
import {
getChatClient, ChatState, ConversationsState, MessagesState
} from '@cstar.help/svelte';
const client = getChatClient();
const chat = new ChatState(client);
const convos = new ConversationsState(client);
let activeThread = $state(null);
let draft = $state('');
async function startChat() {
// Get HMAC signature from your server
const res = await fetch('/api/cstar-auth');
const { signature, customer } = await res.json();
await chat.identify(customer, signature);
const convo = await convos.create({ subject: 'Help needed' });
activeThread = new MessagesState(client, convo.id);
}
async function handleSend() {
await activeThread.send(draft);
draft = '';
}
onDestroy(() => activeThread?.destroy());
</script>
{#if !chat.isIdentified}
<button onclick={startChat}>Chat with us</button>
{:else if activeThread}
{#each activeThread.messages as m (m.id)}
<p><b>{m.sender_name}</b>: {m.content}</p>
{/each}
<input bind:value={draft} />
<button onclick={handleSend}>Send</button>
{/if}6. Article Search
Full-text article search with built-in debounce.
+page.svelte
<!-- src/routes/help/search/+page.svelte -->
<script>
import { onDestroy } from 'svelte';
import { getLibraryClient, ArticleSearchState } from '@cstar.help/svelte';
const client = getLibraryClient();
const searcher = new ArticleSearchState(client);
let query = $state('');
$effect(() => {
searcher.search(query); // 300ms debounce built in
});
onDestroy(() => searcher.destroy());
</script>
<input bind:value={query} placeholder="Search help articles..." />
{#if searcher.isLoading}
<p>Searching...</p>
{:else}
<p>{searcher.totalCount} results</p>
{/if}
{#each searcher.results as a (a.id)}
<a href="/help/{a.slug}">{a.title}</a>
{/each}What's Next?
- Full API Reference — All endpoints and parameters
- SDK Documentation — Detailed Svelte SDK reference
- Webhooks Guide — Event types, signing, and verification
- CLI Reference — Local development tools