Svelte SDK
SvelteKit integration and Svelte actions for Entrolytics
Svelte SDK
The @entrolytics/svelte-sdk package provides SvelteKit integration, Svelte stores, and declarative actions for tracking analytics in Svelte 5 and SvelteKit 2 applications.
Installation
pnpm add @entrolytics/svelte-sdkQuick Start
Initialize in Root Layout
Add Entrolytics to your root layout:
<script lang="ts">
import { initEntrolytics, usePageView } from '@entrolytics/svelte-sdk'
import { page } from '$app/stores'
// Initialize Entrolytics
initEntrolytics({
websiteId: import.meta.env.VITE_ENTROLYTICS_WEBSITE_ID,
host: import.meta.env.VITE_ENTROLYTICS_HOST,
autoTrack: true,
})
// Auto-track page views on navigation
usePageView(page)
</script>
<slot />Add Environment Variables
Create a .env file:
VITE_ENTROLYTICS_WEBSITE_ID=your-website-id
VITE_ENTROLYTICS_HOST=https://entrolytics.devTrack Events
Use the trackEvent function or trackClick action:
<script lang="ts">
import { trackEvent, trackClick } from '@entrolytics/svelte-sdk'
function handleSignup() {
trackEvent('signup', {
plan: 'pro',
source: 'landing-page'
})
}
</script>
<!-- Programmatic tracking -->
<button on:click={handleSignup}>
Sign Up for Pro
</button>
<!-- Declarative tracking with actions -->
<button use:trackClick={{ event: 'cta-click', data: { location: 'hero' } }}>
Get Started
</button>Configuration
Initialization Options
interface EntrolyticsOptions {
/** Website ID (required) */
websiteId: string
/** Link ID for link tracking */
linkId?: string
/** Pixel ID for conversion tracking */
pixelId?: string
/** Custom analytics host URL */
host?: string
/** Auto-track page views (default: true) */
autoTrack?: boolean
/** Tag for A/B testing */
tag?: string
/** Restrict to specific domains */
domains?: string[]
/** Strip query params from URLs */
excludeSearch?: boolean
/** Strip hash fragments from URLs */
excludeHash?: boolean
/** Honor Do Not Track */
respectDnt?: boolean
/** Disable on localhost */
ignoreLocalhost?: boolean
}Example Configuration
<script lang="ts">
import { initEntrolytics } from '@entrolytics/svelte-sdk'
initEntrolytics({
websiteId: 'abc-123-def',
host: 'https://analytics.company.com',
autoTrack: true,
domains: ['example.com', 'app.example.com'],
excludeSearch: true,
ignoreLocalhost: true,
})
</script>Tracking Functions
trackEvent
Track custom events:
<script lang="ts">
import { trackEvent } from '@entrolytics/svelte-sdk'
function handlePurchase(product: Product) {
trackEvent('purchase', {
revenue: product.price,
currency: 'USD',
productId: product.id,
category: product.category
})
}
function handleAddToCart() {
trackEvent('add-to-cart', {
productId: product.id,
quantity: 1
})
}
</script>
<button on:click={handlePurchase}>
Buy Now - ${product.price}
</button>trackPageView
Manually track page views:
<script lang="ts">
import { trackPageView } from '@entrolytics/svelte-sdk'
import { onMount } from 'svelte'
onMount(() => {
// Track current page
trackPageView()
// Or track with custom URL and referrer
trackPageView('/custom-path', 'https://referrer.com')
})
</script>identify
Identify logged-in users:
<script lang="ts">
import { identify } from '@entrolytics/svelte-sdk'
function handleLogin(user: User) {
identify(user.id, {
email: user.email,
name: user.name,
plan: user.subscription,
company: user.company
})
}
</script>Svelte Actions
trackClick
Declaratively track click events:
<script lang="ts">
import { trackClick } from '@entrolytics/svelte-sdk'
</script>
<!-- Basic usage -->
<button use:trackClick={{ event: 'button-click' }}>
Click Me
</button>
<!-- With custom data -->
<button use:trackClick={{
event: 'cta-click',
data: {
location: 'hero',
variant: 'primary'
}
}}>
Get Started
</button>
<!-- Track external links -->
<a
href="https://external-site.com"
use:trackClick={{
event: 'outbound-link',
data: { destination: 'external-site.com' }
}}
>
External Link
</a>trackVisible
Track when elements become visible:
<script lang="ts">
import { trackVisible } from '@entrolytics/svelte-sdk'
</script>
<!-- Track when hero section is visible -->
<section use:trackVisible={{
event: 'section-viewed',
data: { section: 'hero' }
}}>
<h1>Welcome to our site</h1>
</section>
<!-- Track with threshold -->
<div use:trackVisible={{
event: 'pricing-viewed',
data: { section: 'pricing' },
threshold: 0.5 // 50% visible
}}>
Pricing content
</div>SvelteKit Integration
Page View Tracking
Automatically track page views with SvelteKit navigation:
<script lang="ts">
import { page } from '$app/stores'
import { initEntrolytics, usePageView } from '@entrolytics/svelte-sdk'
initEntrolytics({
websiteId: import.meta.env.VITE_ENTROLYTICS_WEBSITE_ID,
})
// Automatically track page changes
usePageView(page)
</script>
<slot />Server-Side Tracking
Track events from SvelteKit server routes:
import { json } from '@sveltejs/kit'
import type { RequestHandler } from './$types'
export const POST: RequestHandler = async ({ request, fetch }) => {
const data = await request.json()
// Track server-side event
await fetch('https://entrolytics.dev/api/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'event',
payload: {
website: import.meta.env.VITE_ENTROLYTICS_WEBSITE_ID,
name: 'subscription-created',
data: {
plan: data.plan,
amount: data.amount
}
}
})
})
return json({ success: true })
}Form Actions
Track in SvelteKit form actions:
import type { Actions } from './$types'
export const actions: Actions = {
default: async ({ request, fetch }) => {
const formData = await request.formData()
// Track form submission
await fetch('https://entrolytics.dev/api/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'event',
payload: {
website: import.meta.env.VITE_ENTROLYTICS_WEBSITE_ID,
name: 'contact-form-submit',
data: {
hasCompany: !!formData.get('company')
}
}
})
})
// Process form...
return { success: true }
}
}Stores
isLoaded
Reactive store that indicates whether the tracking script has loaded:
<script lang="ts">
import { isLoaded } from '@entrolytics/svelte-sdk'
</script>
{#if $isLoaded}
<p>✓ Analytics loaded and ready</p>
{:else}
<p>Loading analytics...</p>
{/if}config
Access the current Entrolytics configuration:
<script lang="ts">
import { config } from '@entrolytics/svelte-sdk'
</script>
<div>
Website ID: {$config.websiteId}
Host: {$config.host}
</div>Advanced Usage
Project Structure
TypeScript Support
Full TypeScript support with exported types:
import type {
EntrolyticsOptions,
TrackEventData,
IdentifyTraits,
TrackClickOptions,
TrackVisibleOptions
} from '@entrolytics/svelte-sdk'
// Type-safe configuration
const options: EntrolyticsOptions = {
websiteId: 'abc-123',
autoTrack: true
}
// Type-safe event data
const eventData: TrackEventData = {
revenue: 99.99,
currency: 'USD',
productId: 'pro-plan'
}
// Type-safe action parameters
const clickOptions: TrackClickOptions = {
event: 'button-click',
data: { location: 'hero' }
}Peer Dependencies
svelte:>=5.0.0web-vitals:>=3.0.0(optional, for Web Vitals tracking)
Web Vitals Tracking (Phase 2)
Track Core Web Vitals (LCP, INP, CLS, FCP, TTFB) automatically:
Automatic Tracking
<script lang="ts">
import { initEntrolytics, initWebVitals } from '@entrolytics/svelte-sdk'
import { onMount } from 'svelte'
import { page } from '$app/stores'
initEntrolytics({
websiteId: import.meta.env.VITE_ENTROLYTICS_WEBSITE_ID,
})
// Initialize automatic Web Vitals tracking
onMount(() => {
initWebVitals()
})
</script>
<slot />Note: Requires the web-vitals package:
pnpm add web-vitalsManual Tracking
Track individual Web Vitals metrics:
<script lang="ts">
import { trackVital } from '@entrolytics/svelte-sdk'
import { onLCP, onINP, onCLS } from 'web-vitals'
import { onMount } from 'svelte'
onMount(() => {
onLCP((metric) => trackVital({
metric: 'LCP',
value: metric.value,
rating: metric.rating,
delta: metric.delta,
id: metric.id,
navigationType: metric.navigationType,
}))
onINP((metric) => trackVital({
metric: 'INP',
value: metric.value,
rating: metric.rating,
}))
onCLS((metric) => trackVital({
metric: 'CLS',
value: metric.value,
rating: metric.rating,
}))
})
</script>Form Analytics (Phase 2)
Track form interactions, field completions, and abandonment:
Using the trackForm Action
The simplest way to track forms:
<script lang="ts">
import { trackForm } from '@entrolytics/svelte-sdk'
</script>
<form use:trackForm={{ formId: 'contact', formName: 'Contact Form' }}>
<input name="name" type="text" placeholder="Name" />
<input name="email" type="email" placeholder="Email" />
<textarea name="message" placeholder="Message"></textarea>
<button type="submit">Send</button>
</form>This automatically tracks:
- Form start (first field interaction)
- Field focus/blur with time spent
- Form submission
- Form abandonment (user leaves without submitting)
Using createFormTracker
For more control, use the form tracker factory:
<script lang="ts">
import { createFormTracker } from '@entrolytics/svelte-sdk'
const tracker = createFormTracker('signup-form', 'Signup Form')
async function handleSubmit() {
const success = await submitForm()
tracker.trackSubmit(success)
}
</script>
<form on:submit|preventDefault={handleSubmit}>
<input
name="email"
type="email"
on:focus={() => tracker.trackFieldFocus('email', 'email', 0)}
on:blur={() => tracker.trackFieldBlur('email', 'email', 0)}
/>
<input
name="password"
type="password"
on:focus={() => tracker.trackFieldFocus('password', 'password', 1)}
on:blur={() => tracker.trackFieldBlur('password', 'password', 1)}
/>
<button type="submit">Sign Up</button>
</form>Manual Form Event Tracking
For complete control:
<script lang="ts">
import { trackFormEvent } from '@entrolytics/svelte-sdk'
async function handleSubmit() {
const success = await submitForm()
await trackFormEvent({
eventType: 'submit',
formId: 'checkout-form',
formName: 'Checkout',
success,
})
}
function handleFieldError(fieldName: string, error: string) {
trackFormEvent({
eventType: 'field_error',
formId: 'checkout-form',
fieldName,
errorMessage: error,
})
}
</script>Form Event Types:
| Event | Description |
|---|---|
start | User started interacting with the form |
field_focus | User focused on a field |
field_blur | User left a field (includes time spent) |
field_error | Validation error on a field |
submit | Form was submitted |
abandon | User left without submitting |
Features
- ✅ Svelte 5 and SvelteKit 2 support
- ✅ Declarative Svelte actions (
trackClick,outboundLink,trackForm) - ✅ Reactive Svelte stores (
isLoaded,isReady) - ✅ Auto-track page views with SvelteKit navigation
- ✅ Server-side tracking in
+server.tsfiles - ✅ Form actions integration
- ✅ Web Vitals tracking (LCP, INP, CLS, FCP, TTFB)
- ✅ Form analytics (focus, blur, submit, abandonment)
- ✅ TypeScript-first with full type safety
- ✅ SSR compatible
- ✅ Zero dependencies (besides Svelte)
Support
- GitHub Issues
- Email: hey@entrolytics.dev