PostHog makes it easy to get data about traffic and usage of your Svelte app. Integrating PostHog into your site enables analytics about user behavior, custom events capture, session recordings, feature flags, and more.
This guide walks you through integrating PostHog into your SvelteKit app using the JavaScript Web and Node.js SDKs.
Client-side setup
Install posthog-js
using your package manager:
yarn add posthog-js# ornpm install --save posthog-js
Then, if you haven't created a root layout already, create a new file called +layout.js
in your src/routes
folder In this file, check the environment is the browser, and initialize PostHog if so. You can get both your API key and instance address in your project settings:
import posthog from 'posthog-js'import { browser } from '$app/environment';export const load = async () => {if (browser) {posthog.init('<ph_project_api_key>',{ api_host: 'https://us.i.posthog.com', person_profiles: 'identified_only' })}return};
❗️ If you intend on using session replays with a server-side rendered Svelte app ensure that your asset URLs are configured to be relative.
Tracking pageviews and pageleaves
PostHog only captures pageview events when a page load is fired. Since Svelte creates a single-page app, this only happens once, and the router handles subsequent page changes.
If we want to capture every route change, we must write code to capture pageviews that integrates with the router.
To do this, set up beforeNavigate
and afterNavigate
interceptors in a new file routes/+layout.svelte
to capture $pageview
and $pageleave
events:
<script>import posthog from 'posthog-js'import { browser } from '$app/environment';import { beforeNavigate, afterNavigate } from '$app/navigation';if (browser) {beforeNavigate(() => posthog.capture('$pageleave'));afterNavigate(() => posthog.capture('$pageview'));}</script><slot></slot>
To make sure we don't double count pageviews and pageleaves, we also need to adjust our PostHog initialization in routes/+layout.js
to set capture_pageview
and capture_pageleave
to false.
import posthog from 'posthog-js'import { browser } from '$app/environment';export const load = async () => {if (browser) {posthog.init('<ph_project_api_key>',{api_host:'https://us.i.posthog.com',person_profiles: 'identified_only',capture_pageview: false,capture_pageleave: false})}return};
Server-side setup
Install posthog-node
using your package manager:
yarn add posthog-node# ornpm install --save posthog-node
Then, initialize the PostHog Node client where you'd like to use it on the server side. For example, in a load function:
import { PostHog } from 'posthog-node';export async function load() {const posthog = new PostHog('<ph_project_api_key>',{ host: 'https://us.i.posthog.com' });posthog.capture({distinctId: 'distinct_id_of_the_user',event: 'event_name',})await posthog.shutdown()}
Note: Make sure to always call
posthog.shutdown()
after capturing events from the server-side. PostHog queues events into larger batches, and this call forces all batched events to be flushed immediately.
Configuring session replay for server-side rendered apps
By default, Svelte uses relative asset paths during server-side rending. This causes issues with PostHog's ability to record sessions.
To fix this, set the config to not use relative paths in svelte.config.js
:
kit: {paths: {relative: false,},},
Next steps
For any technical questions for how to integrate specific PostHog features into Svelte (such as analytics, feature flags, A/B testing, surveys, etc.), have a look at our JavaScript Web and Node SDK docs.
Alternatively, the following tutorials can help you get started: