Svelte stores, actions, and components for ZoriHQ Analytics.
npm install @zorihq/svelte
# or
pnpm add @zorihq/svelte
# or
yarn add @zorihq/svelteInitialize once in your root component or layout:
<!-- +layout.svelte or App.svelte -->
<script lang="ts">
import { initZori } from '@zorihq/svelte';
const zori = initZori({
publishableKey: 'your-publishable-key',
baseUrl: 'https://ingestion.zorihq.com/ingest', // optional
comebackThreshold: 30000, // optional
trackQuickSwitches: false, // optional
});
</script>
<slot />Use the ZoriProvider component:
<!-- App.svelte -->
<script lang="ts">
import { ZoriProvider } from '@zorihq/svelte';
</script>
<ZoriProvider config={{ publishableKey: 'your-key' }}>
<slot />
</ZoriProvider><script lang="ts">
import { getZori } from '@zorihq/svelte';
const zori = getZori();
async function handlePurchase() {
await zori.track('purchase_completed', {
product_id: 'prod_123',
amount: 99.99,
});
}
async function handleLogin() {
await zori.identify({
app_id: 'user_123',
email: 'user@example.com',
fullname: 'John Doe',
});
}
</script>
<button on:click={handlePurchase}>Complete Purchase</button>
<button on:click={handleLogin}>Login</button>Automatically track clicks on any element:
<script lang="ts">
import { trackClick } from '@zorihq/svelte';
</script>
<button
use:trackClick={{ eventName: 'signup_clicked', properties: { location: 'header' } }}
>
Sign Up
</button>
<a
href="/pricing"
use:trackClick={{ eventName: 'cta_clicked', properties: { cta: 'pricing' } }}
>
View Pricing
</a>Auto-track page views on component mount:
<script lang="ts">
import { usePageView } from '@zorihq/svelte';
export let productId: string;
usePageView({
page_type: 'product',
product_id: productId,
});
</script>
<div>Product {productId}</div>Track events on component mount:
<script lang="ts">
import { useTrackEvent } from '@zorihq/svelte';
export let userId: string;
useTrackEvent('profile_viewed', {
user_id: userId,
});
</script>
<div>User Profile</div>Identify users on component mount:
<script lang="ts">
import { useIdentify } from '@zorihq/svelte';
export let user: any;
useIdentify(
user
? {
app_id: user.id,
email: user.email,
fullname: user.name,
}
: null
);
</script>
<div>{user?.name}</div><script lang="ts">
import { getZori } from '@zorihq/svelte';
const zori = getZori();
let searchQuery = '';
let results = [];
// Track when reactive values change
$: if ($zori.isInitialized && searchQuery) {
zori.track('search_performed', {
query: searchQuery,
result_count: results.length,
});
}
</script>
<input bind:value={searchQuery} placeholder="Search..." />
<div>{results.length} results</div><script lang="ts">
import { getZori } from '@zorihq/svelte';
const zori = getZori();
</script>
{#if $zori.isInitialized}
<p>Analytics Ready!</p>
{:else}
<p>Loading analytics...</p>
{/if}<script lang="ts">
import { initZori } from '@zorihq/svelte';
import { page } from '$app/stores';
const zori = initZori({
publishableKey: import.meta.env.VITE_ZORI_KEY,
});
// Track page views on route change
$: if ($zori.isInitialized && $page.url.pathname) {
zori.track('page_view', {
page_title: document.title,
page_path: $page.url.pathname,
page_search: $page.url.search,
});
}
</script>
<slot />Create .env:
VITE_ZORI_KEY=your-publishable-keyCreate a new Zori store instance.
import { createZoriStore } from '@zorihq/svelte';
const zori = createZoriStore({
publishableKey: 'your-key',
baseUrl: 'https://ingestion.zorihq.com/ingest', // optional
comebackThreshold: 30000, // optional
trackQuickSwitches: false, // optional
});Initialize global Zori store (recommended for app-wide usage).
import { initZori } from '@zorihq/svelte';
const zori = initZori({ publishableKey: 'your-key' });Get the global Zori store instance.
import { getZori } from '@zorihq/svelte';
const zori = getZori();The store exposes:
isInitialized: Readable store indicating if ZoriHQ is readytrack(eventName, properties): Track custom eventsidentify(userInfo): Identify usersgetVisitorId(): Get the visitor IDgetSessionId(): Get the current session IDsetConsent(preferences): Set GDPR consent preferencesoptOut(): Opt out of tracking completelyhasConsent(): Check if user has given consent
<button use:trackClick={{ eventName: 'click', properties: {} }}>
Click Me
</button>usePageView(properties?): Track page view on mountuseTrackEvent(eventName, properties?): Track event on mountuseIdentify(userInfo): Identify user on mount
This package includes full TypeScript support:
import type {
ZoriConfig,
ZoriStore,
ConsentPreferences,
UserInfo,
} from '@zorihq/svelte';This library follows Svelte's stores pattern:
- Use
$to auto-subscribe in components - Stores are reactive and update automatically
- Automatic cleanup on component destroy
MIT