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

# Frameworks

> Which snippet settings to use with Next.js, React, Remix, Shopify Hydrogen, Vue, Nuxt, SvelteKit, Astro, Gatsby and Angular.

pagent works with JavaScript frameworks. The snippet is the same everywhere; only where you put it and one setting differ. Start with the table, then open your framework's guide.

## Recommended settings

| Framework | Where the snippet goes | `data-await-hydration` |
| - | - | - |
| [Next.js](https://www.pagent.ai/docs/install/nextjs.md) (App Router and Pages Router) | `<head>` in `app/layout.tsx` or `pages/_document.tsx` | `"true"` |
| [Remix and React Router](https://www.pagent.ai/docs/install/react.md#remix-and-react-router-framework-mode) | `<head>` in `app/root.tsx` | `"true"` |
| [Shopify Hydrogen](https://www.pagent.ai/docs/install/hydrogen.md) | `<head>` in `app/root.tsx`, with the nonce | `"true"` |
| [Gatsby](https://www.pagent.ai/docs/install/gatsby.md) | `gatsby-ssr.js` | `"true"` |
| [Nuxt 3 and 4](https://www.pagent.ai/docs/install/vue.md#nuxt) | `app.head.script` in `nuxt.config.ts` | `"true"` |
| [Astro](https://www.pagent.ai/docs/install/astro.md) | `<head>` of your layout, with `is:inline` | `"true"` if you use `client:load` or `client:idle` islands |
| [React with Vite or Create React App](https://www.pagent.ai/docs/install/react.md) | `<head>` in `index.html` | not needed |
| [Vue with Vite](https://www.pagent.ai/docs/install/vue.md) | `<head>` in `index.html` | not needed |
| [SvelteKit](https://www.pagent.ai/docs/install/sveltekit.md) | `<head>` in `src/app.html` | not needed |
| [Angular](https://www.pagent.ai/docs/install/angular.md) | `<head>` in `src/index.html` | not needed |

## Rules for every framework

* **Use a plain `<script>` tag.** Don't add `async`, `defer` or `type="module"`, and don't load it through a framework's script component unless the guide says so. pagent has to run before the page shows so visitors never see the original flash.

* **Write `="true"`.** A bare attribute such as `data-await-hydration` without a value counts as off.

* **Page changes are tracked for you.** pagent follows client-side navigation through the History API (`pushState`, `replaceState`, back and forward). It records a new page view and applies the right tests on each route. You don't need to call anything.

* **Hash routing is the exception.** With routes like `/#/pricing`, tell pagent about each route change:

  ```js theme={"dark"}
  window._pgnt = window._pgnt || [];
  window._pgnt.push({ kind: "navigate" });
  ```

  Send it on route changes only, not on the first page load: pagent already counts that one.

* **Don't define `window.pagent` yourself.** If it exists before the snippet runs, pagent doesn't start. Use the `window._pgnt` queue to send events before the SDK has loaded.

## What `data-await-hydration` does

Server-rendered frameworks send finished HTML, then "hydrate" it with JavaScript. Hydration can overwrite a change pagent made a moment earlier. With `data-await-hydration="true"`, pagent waits until hydration has finished, then applies the variant. The page stays hidden while it waits: up to 0.75 seconds by default, longer on slow connections.

pagent recognizes hydration for Next.js (both routers), Remix and React Router, Gatsby, Nuxt 3 and later, Astro islands, and React apps on `#root`. For SvelteKit, Angular and client-rendered Vue, it can't tell when hydration is done, so the setting doesn't help there.

If hydration takes longer than the wait, pagent shows the original page for that page view and only measures it, without a variant. Three settings change this:

| Setting | Default | Use it when |
| - | - | - |
| `data-hydration-timeout="800"` | `500` (milliseconds) | Your pages hydrate slowly, for example with large client bundles. |
| `data-hydration-timeout-mode="apply"` | `drop` | Many visits time out. pagent then applies the variant anyway and restores it for about three seconds if hydration overwrites it. A brief flicker is possible. |
| `data-hydration-connection-scaling="false"` | on | You don't want the wait stretched on slow mobile connections (up to 1.5 seconds). |

Try any of them on a preview link first by adding `?pagent_hydration_timeout=800` or `?pagent_hydration_timeout_mode=apply` to the URL. The [developer guide](https://www.pagent.ai/docs/guides/integration/sdk-integration.md) explains every option in detail.

## Content Security Policy

If your site sends a Content Security Policy, allow pagent:

| Directive | Value |
| - | - |
| `script-src` | `https://cdn.pagent.ai` |
| `connect-src` | `https://cdn.pagent.ai https://ingest.pagent.ai https://app.pagent.ai` |
| `style-src` | `'unsafe-inline'`, or the hash `'sha256-SAedXe3plfSeBDFpbDKWxZd5IvQUQhunmaNfgiJuP38='`, for the short page hide |

Tests that change JavaScript also need `'unsafe-eval'` in `script-src`. Without it, those JavaScript changes don't apply; everything else still runs. See [security headers](https://www.pagent.ai/docs/guides/integration/security-headers.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.