# Install on Next.js

> Add Kymo to a Next.js app. Use a plain script tag in the root layout, not next/script, because beat.js reads document.currentScript.

Canonical: https://kymo.in/docs/guides/nextjs
Last updated: 2026-07-21

Add the tag to your root layout so it loads on every route.

## App Router

Put a plain `<script>` in the `<head>` of `app/layout.js` (or `.tsx`):

```jsx
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <head>
        <script defer src="https://kymo.in/beat.js" data-site="yoursite.com"></script>
      </head>
      <body>{children}</body>
    </html>
  );
}
```

> **Warning:** Use a plain `<script>` tag, not `next/script`. `beat.js` reads `document.currentScript` to find its own `data-site`, and a dynamically injected `next/script` leaves `currentScript` null, so the tracker silently does nothing. A parser-inserted tag in `<head>` works correctly.

## Pages Router

Add the same tag to `pages/_document.js` inside `<Head>`:

```jsx
import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html>
      <Head>
        <script defer src="https://kymo.in/beat.js" data-site="yoursite.com"></script>
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}
```

## Client-side navigation

Kymo tracks `history.pushState` navigations automatically, so the App Router and `next/link` client transitions are counted as pageviews without extra work.

Then [verify events arrive](https://kymo.in/docs/start/verify).
