Plausible.io Custom URLs with SvelteKit

Written

Plausible Analytics has a feature which lets you use custom URLs to help avoid adblockers and get better counts. Plausible is committed to respecting privacy, so I feel this is OK to do. (And they address the topic here).

This site is built with SvelteKit and hosted on Vercel, and so none of the normal methods documented by Plausible work with this particular combination. But it's pretty simple to get going. Everything you see here except for the Vercel-specific edge function configuration will apply to other hosts too.

We need two routes: one for the script itself, and another route to proxy events. I chose to place both of these routes under the /plas path.

First, the route for fetching the script itself.

// src/routes/plas/script.js/+server.ts

export const config = {
  // Vercel-specific
  runtime: 'edge',
};

export function GET({ fetch }) {
  return fetch('https://plausible.io/js/script.js');
}

This has a bit of configuration to run this route as an edge function, and then it just performs its own request for the actual Plausible script.

Next, you need a route for the Plausible script to send events to. This is similar to the previous route, but it also passes the relevant headers and body from the client through to Plausible.

// src/routes/plas/event/+server.ts

export const config = {
  // Vercel-specific
  runtime: 'edge',
};

export async function POST({ request, fetch }) {
  let response = fetch('https://plausible.io/api/event', {
    method: request.method,
    headers: request.headers,
    body: request.body,
  });

  return response;
}

Finally, in app.html we just include the script, with the appropriate paths for the script and event routes.

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Other head contents -->
    <script
      async
      defer
      data-domain="your-domain.com"
      data-api="/plas/event"
      src="/plas/script.js"
    ></script>
  </head>
  <body><!-- body contents --></body>
</html>

And that's it!


Thanks for reading! If you have any questions or comments, please send me a note on Twitter.