---
title: "Static sites"
description: "Add CanaryLytics to a plain HTML or statically-generated site with one script tag in your shared layout. No build step, no configuration."
last_updated: "2026-07-30"
---

# Static sites

Static sites, whether hand-written HTML or the output of a static site generator, are the simplest case and work out of the box. Paste the snippet into your shared layout or template so it lands on every page:

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>My site</title>
    <script src="https://cdn.analytics.canarycoders.es/lytics.js" data-domain="myapp.com" defer></script>
  </head>
  <body>
    ...
  </body>
</html>
```

Each full page load fires one `page_view` (path + query string, no hash). Same-origin link clicks are tracked automatically; external links are deliberately left untracked. There is no client-side router to patch, so this is the entire integration.

<Aside type="note" title="Content-Security-Policy">
  If the site sets a CSP, add the CDN to `script-src` and the API origin to `connect-src`, or the browser silently blocks the request before it is even sent:

  ```
  Content-Security-Policy: script-src 'self' https://cdn.analytics.canarycoders.es; connect-src 'self' https://api.analytics.canarycoders.es;
  ```

  A CSP block never reaches the server, so `GET /v1/validate` can't see it. See [troubleshooting](/docs/troubleshooting/#content-security-policy).
</Aside>

## Related

<CardGrid>
  <LinkCard title="Framework integrations" description="Where the tag goes in Vite, Next.js, Astro, and TanStack Start." href="/docs/environments/framework-integrations/" />
  <LinkCard title="Script reference" description="Every attribute the snippet reads." href="/docs/tracking/script-reference/" />
</CardGrid>

## Sitemap

- [Docs sitemap](https://analytics.canarycoders.es/docs/sitemap.md)
- [Full documentation as a single file](https://analytics.canarycoders.es/llms-full.txt)
