Skip to content

SvelteKit

Terminal window
npx @plaintrace/cli init --site <site id> --endpoint https://collect.plaintrace.dev

The CLI adds the script to src/app.html. By hand:

<!-- src/app.html, inside <head> -->
<script>if(!window.px){var p=window.px=function(){p.q.push(arguments)};p.q=[];p.s=1}</script>
<script async src="https://collect.plaintrace.dev/t.js" data-site="<site id>"></script>

Client-side navigations are recorded automatically.

src/hooks.server.ts
import { env } from '$env/dynamic/private'
import { createClient } from '@plaintrace/server'
import type { Handle } from '@sveltejs/kit'
const analytics = createClient({ key: env.ANALYTICS_KEY!, endpoint: 'https://collect.plaintrace.dev', ipHeader: 'x-real-ip' })
export const handle: Handle = async ({ event, resolve }) => {
// waitUntil keeps recording alive after the response on the Cloudflare adapter; elsewhere it is not needed.
const res = await analytics.handle(event.request, { waitUntil: (p) => event.platform?.context?.waitUntil(p) })
return res ?? resolve(event)
}

Set ipHeader to the header your host or proxy overwrites with the visitor’s address (see first-party proxy).