> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bily.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Page views

> Record every page once: automatically on the first load, explicitly on later SPA routes.

Use the exact event name `PageView`.

## Let Bily record the first page

The Bily browser script records the first page view when the document loads. This works the same whether you use the raw script or initialize Bily through `@bilyai/js`.

<Warning>
  Do not call `track("PageView")` during the initial page or component mount. It would duplicate the automatic event.
</Warning>

Traditional multi-page sites need no manual page-view code. Each full navigation loads a new document and records one initial event.

## Record each later SPA route

Single-page applications do not load a new document for each route. After the router commits a later URL, send:

```typescript theme={null}
import { track } from "@bilyai/js";

track("PageView", {
  sourceUrl: window.location.href,
  pageTitle: document.title,
});
```

Set `sourceUrl` to the complete current URL. Send the event after the page title and route state are current.

## Skip the first route and repeated URLs

Save the current URL before you listen for later navigation.

```typescript route-tracking.ts theme={null}
import { track } from "@bilyai/js";

let previousUrl = window.location.href;

export function onRouteCommitted() {
  const currentUrl = window.location.href;
  if (currentUrl === previousUrl) return;

  previousUrl = currentUrl;
  track("PageView", {
    sourceUrl: currentUrl,
    pageTitle: document.title,
  });
}
```

Connect `onRouteCommitted()` to your router's after-navigation callback. Do not call it to initialize the listener.

## Use your framework's router

<CardGroup cols={2}>
  <Card title="React Router" icon="atom" href="/sdk/react">
    Track pathname, search, and hash changes from one component.
  </Card>

  <Card title="Next.js" icon="layers" href="/sdk/nextjs">
    Track App Router and Pages Router navigation from one shared component.
  </Card>
</CardGroup>

## Confirm every page appears once

* The event name is exactly `PageView`.
* The initial document relies on the automatic event.
* Later browser routes call `track()` after the route commits.
* `sourceUrl` contains `window.location.href`.
* `pageTitle` contains the final `document.title`.
* A rerender at the same URL does not emit another event.

<Card title="Verify page views" icon="circle-check" href="/guides/verification">
  Test direct loads, reloads, route transitions, and browser history.
</Card>
