# Framework Installation Guides

Use the canonical domain for your authorized site and install the tracker once. No API credential belongs in the tag. The examples use the existing built asset, `https://purestats.io/pf.min.js`, with no invented versioned URL.

## HTML

Add to the shared `<head>`:

```html
<script defer src="https://purestats.io/pf.min.js" data-domain="example.com"></script>
```

Check CSP permits `https://purestats.io` in `script-src` and `connect-src`. Do not track preview or development deployments unless you deliberately configure an authorized test environment. [Existing HTML guide](/docs/installation/plain-html.md).

## React

For a Vite-style React application, put the same tag in `index.html`, outside component render cycles. Do not append a new tag every time a component mounts. Ordinary React Router URL transitions are observed through the History API; avoid adding a second pageview hook.

For memory routers or screens that never update the browser URL, call the existing JavaScript API only after checking that automatic pageviews do not cover the transition:

```js
window.purestats?.trackPageview('/checkout');
```

Keep custom event properties non-identifying. [Existing React guide](/docs/installation/react.md) and [SPA routing](/docs/installation/spa-routing.md).

## Next.js

Load the tracker once in the App Router root layout:

```tsx
import Script from 'next/script';
import type { ReactNode } from 'react';

export default function RootLayout({ children }: { children: ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://purestats.io/pf.min.js"
          strategy="afterInteractive"
          data-domain="example.com"
        />
      </body>
    </html>
  );
}
```

For the Pages Router, place the `Script` once in `pages/_app.tsx`, beside the page component. A public domain configuration variable may be exposed to the browser; an OAuth client secret or access token must not be. Check client transitions for one pageview each before adding routing callbacks. [Existing Next.js guide](/docs/installation/nextjs.md).

## Laravel / Blade

Put the HTML tag in the shared Blade layout's `<head>`, not every child view. Escape a configured public domain through Blade:

```blade
<script defer src="https://purestats.io/pf.min.js" data-domain="{{ config('services.purestats.domain') }}"></script>
```

Define `services.purestats.domain` in your application's configuration with the canonical site domain. It is public configuration, not a credential. Do not embed `env('PURESTATS_CLIENT_SECRET')` or an API token in Blade. OAuth API calls belong in server-side services with scoped access. Laravel applications using Inertia or client-side navigation follow the same one-tag and one-pageview checks as other SPAs.

## Consent and Optional Features

Use site settings for consent, DNT, exclusions and enabled modules. Do not bypass a configured consent requirement merely to create a green test result. The base tracker loads the enabled feature modules; do not install every optional module as an extra unconditional script.

Read [Tracking script reference](/docs/reference/tracking-script.md), [JavaScript API](/docs/reference/javascript-api.md), [Consent mode](/docs/privacy/consent-mode.md), [Proxy](/docs/agents/proxy.md) and [Testing](/docs/agents/testing.md).
