# Astro

URL: https://pieowl.com/docs/sdks/astro





<Callout>
  Looking for a step-by-step tutorial? Read the [Astro analytics guide](/guides/astro-analytics).
</Callout>

Track pages [#track-pages]

Add the script to your root layout and replace `YOUR_CLIENT_ID` with your client ID. `is:inline` keeps Astro from bundling it. It works with static and server-rendered pages, and with View Transitions.

```astro title="src/layouts/Layout.astro"
<html>
  <head>
    <script is:inline src="https://pieowl.com/pieowl.js" data-client-id="YOUR_CLIENT_ID" defer></script>
  </head>
  <body>
    <slot />
  </body>
</html>
```

What the script collects by itself (page views, outside link clicks, `data-track` clicks) is set in **Settings → Site → What Pieowl counts**, not in code. For options that need code, see [Options in code](/docs/sdks/script#options-in-code).

Tracking events [#tracking-events]

Call `window.pieowl`, or add `data-track` attributes. `data-track` needs **Clicks you marked in your code** to be on in Settings → Site (it is by default).

```astro
<button onclick="window.pieowl('track', 'clicky')">Click me</button>
<button data-track="clicky" data-prop1="prop1" data-prop2="prop2">Click me</button>
```

```astro
<script>
  document.querySelector('#signup')?.addEventListener('click', () => {
    window.pieowl('track', 'signup_clicked', { location: 'header' });
  });
</script>
```

Identifying users [#identifying-users]

<PersonalDataWarning />

When you know the user on the server, render the call into the page:

```astro
---
const user = Astro.locals.user;
---

{user && (
  <script is:inline define:vars={{ user: { profileId: user.id, email: user.email } }}>
    window.pieowl('identify', user);
  </script>
)}
```

This call runs before `pieowl.js` has loaded, so add the [queue line](/docs/sdks/script#calling-pieowl-before-the-script-loads) before the script tag in your layout. `setGlobalProperties`, `increment`, `decrement` and `clear` work the same way. See the [Script Tag](/docs/sdks/script#usage) docs.

Track AI crawlers and bots [#track-ai-crawlers-and-bots]

On server-rendered sites (an Astro adapter with `output: 'server'` or on-demand pages), report the bots the script can't see:

```bash
npm install @pieowl/bots
```

```ts title="src/middleware.ts"
import { trackBotRequest } from '@pieowl/bots';
import { defineMiddleware } from 'astro:middleware';

export const onRequest = defineMiddleware((context, next) => {
  trackBotRequest(context.request, {
    clientId: import.meta.env.PIEOWL_CLIENT_ID,
    clientSecret: import.meta.env.PIEOWL_CLIENT_SECRET,
  });
  return next();
});
```

Static sites have no server to see the bots. Read more in [AI crawlers and bots](/docs/ai-bots).

Avoid ad blockers [#avoid-ad-blockers]

On a server-rendered site, serve the script and send events through your own domain with an endpoint:

```ts title="src/pages/api/pieowl/[...path].ts"
import { createRouteHandler } from '@pieowl/bots/route-handler';

const handler = createRouteHandler();

export const prerender = false;
export const ALL = ({ request }: { request: Request }) => handler(request);
```

Then switch to the [`init` form](/docs/sdks/script#options-in-code), set `apiUrl: '/api/pieowl'` in `init`, and load the script from `/api/pieowl/pieowl.js`. See [Avoid ad blockers](/docs/adblockers).

Server-side events [#server-side-events]

Use the [JavaScript SDK](/docs/sdks/javascript) (`@pieowl/sdk`) with your client secret in endpoints and server-rendered pages.
