> ## 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.

# SDK

> JavaScript SDK Integration Guide

To dynamically manage A/B testing and personalized elements on your website, you need to integrate the pagent SDK script directly into your webpage.

Choose **one** of two loading strategies and follow the steps below.

## 1. Pick a loading strategy

| Strategy                        | When to use                                                                                     | Requirements                                                    |
| ------------------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| **Synchronous** (blocking)      | You want the simplest setup and can tolerate the script being parsed during the initial render. | Only the SDK tag inside `<head>`.                               |
| **Asynchronous** (non-blocking) | You need the main thread free during the first paint (e.g. performance-critical landing pages). | A short anti-flicker snippet **plus** the SDK tag with `async`. |

Both variants require the `data-client-key` attribute that you will find in your pagent workspace.

***

## 2. Synchronous loading

Add the tag **as early as possible** inside the `<head>` tag:

```html theme={"dark"}
<head>
  <script
    src="https://cdn.pagent.ai/js/sdk.js"
    data-client-key="YOUR_CLIENT_KEY">
  </script>
</head>
```

This ensures the SDK executes during the initial render cycle, preventing visual flashes.
(We recommend against loading the SDK through Google Tag Manager or similar tools that inject scripts after the page has loaded, as this may cause flickering.)

***

## 3. Asynchronous loading with anti-flicker

1. Paste the anti-flicker snippet right **after the opening `<head>` tag**:

```html theme={"dark"}
<script>
    (() => {
        const MAX_WAIT = 500; // Your maximum wait time for our script to load
        const STYLE_ID = "pagent-body";
        if (window.pagentInit) return;
        window.pagentInit = true;

        const head = document.head || document.getElementsByTagName("head")[0];
        if (!head || document.getElementById(STYLE_ID)) return;

        const style = document.createElement("style");
        style.id = STYLE_ID;
        style.textContent = "body{opacity:0 !important; pointer-events:none !important}";
        head.appendChild(style);

        let shown = false;
        let timeoutId = setTimeout(() => display("timeout"), MAX_WAIT);

        function display(cause) {
            if (shown) return;
            if (style.parentNode) style.parentNode.removeChild(style);
            shown = true;
            if (timeoutId) {
                clearTimeout(timeoutId);
                timeoutId = 0;
            }
            window.pagentTimeout = cause === "timeout";
        }
        
        window.pagentDisplayPage = () => display("engine");
    })();
</script>
```

Feel free to lower `MAX_WAIT` if you can accept the risk that variations might not be applied in time.

If you prefer a minified version:

```html theme={"dark"}
<script>
  ((e,t,n)=>{const o="pagent-body";if(e.pagentInit)return;e.pagentInit=!0;const i=t.head||t.getElementsByTagName("head")[0];if(!i||t.getElementById(o))return;const a=t.createElement("style");a.id=o,a.textContent="body{opacity:0 !important; pointer-events:none !important}",i.appendChild(a);let p=!1,d=setTimeout((()=>m("timeout")),n);function m(t){p||(a.parentNode&&a.parentNode.removeChild(a),p=!0,d&&(clearTimeout(d),d=0),e.pagentTimeout="timeout"===t)}e.pagentDisplayPage=()=>m("engine")})(window,document,1000);
</script>
```

2. Load the SDK asynchronously:

```html theme={"dark"}
<head>
  <script
    src="https://cdn.pagent.ai/js/sdk.js"
    data-client-key="YOUR_CLIENT_KEY"
    async
    fetchpriority="high">
  </script>
</head>
```

***

## 4. Skip page hide (no flicker)

If you want to disable the page-hiding mechanism entirely, you can add the `data-skip-page-hide="true"` attribute to the SDK script tag. This prevents the SDK from hiding the page during initialization.

```html theme={"dark"}
<head>
  <script
    src="https://cdn.pagent.ai/js/sdk.js"
    data-client-key="YOUR_CLIENT_KEY"
    data-skip-page-hide="true">
  </script>
</head>
```

You can combine this with the `async` attribute for asynchronous loading:

```html theme={"dark"}
<head>
  <script
    src="https://cdn.pagent.ai/js/sdk.js"
    data-client-key="YOUR_CLIENT_KEY"
    data-skip-page-hide="true"
    async
    fetchpriority="high">
  </script>
</head>
```

**What this does:**

* ✅ **No page hiding** – The page remains visible throughout initialization
* ✅ **No flicker** – Users won't see the page fade in/out
* ⚠️ **Content overwrite** – Variations are applied directly to the visible page
* ⚠️ **Brief flash possible** – Users may see the original content briefly before it's replaced with variations

**When to use this:**

* When you prefer no visual hiding/flicker over perfect content replacement
* When your variations are subtle and a brief flash is acceptable
* When you want to avoid any opacity changes to the page body
* When using with asynchronous loading and you don't want the anti-flicker snippet

**Note:** If you use `data-skip-page-hide="true"` with asynchronous loading, you do **not** need to include the anti-flicker snippet from section 3.

***

## 5. Analytics only mode

For scenarios where you only need to track analytics data without running tests, you can use the SDK in "analytics only mode" by adding the `data-analytics-only="true"` attribute:

```html theme={"dark"}
<head>
  <script
    src="https://cdn.pagent.ai/js/sdk.js"
    data-client-key="YOUR_CLIENT_KEY"
    data-analytics-only="true">
  </script>
</head>
```

**What this mode does:**

* ✅ Tracks analytics and user behavior data
* ✅ Makes the `_pgnt` property available for custom tracking
* ❌ **Never loads or runs A/B tests**
* ❌ **Never overwrites variations or content**
* ❌ **Never loads anti-flicker mechanisms**

This mode is perfect for:

* Analytics tracking without experimentation
* Gradual migration from other analytics tools
* Testing pagent's data collection before enabling experiments
* Compliance scenarios where you need data but not content changes

***

## 6. Wait for framework hydration

If your site uses a JavaScript framework like React, Next.js, Gatsby, or Nuxt, the framework "hydrates" the server-rendered HTML after the page loads. This hydration can overwrite any DOM changes the SDK made during initialization.

Adding `data-await-hydration="true"` tells the SDK to wait until the framework has finished hydrating before applying variations, so your changes persist.

```html theme={"dark"}
<head>
  <script
    src="https://cdn.pagent.ai/js/sdk.js"
    data-client-key="YOUR_CLIENT_KEY"
    data-await-hydration="true">
  </script>
</head>
```

You can combine this with other attributes:

```html theme={"dark"}
<head>
  <script
    src="https://cdn.pagent.ai/js/sdk.js"
    data-client-key="YOUR_CLIENT_KEY"
    data-await-hydration="true"
    async
    fetchpriority="high">
  </script>
</head>
```

**How it works:**

* The SDK detects common framework root elements (e.g. `__next`, `___gatsby`, `__nuxt`, `root`)
* It waits for the framework to attach to the DOM, confirming hydration is complete
* Once hydrated, the SDK applies variations safely without them being overwritten
* If no framework is detected, the SDK proceeds immediately
* A timeout (500 ms) ensures the page is never blocked indefinitely

**When to use this:**

* When using Next.js, Gatsby, Nuxt, or other frameworks with server-side rendering
* When you notice variations briefly appear and then revert after page load
* When your framework hydration overwrites SDK-applied changes

**Try it before committing:**
You don't need to add the attribute right away. Append `?pagent_await_hydration=true` to any preview URL to test the behavior first:

```
https://yoursite.com/landing-page?pagent_await_hydration=true
```

If the variations apply correctly with the parameter, add `data-await-hydration="true"` to your script tag permanently.

**When you don't need this:**

* Static HTML sites with no JavaScript framework
* Client-side-only SPAs that don't server-render (no hydration step)
* Sites where the SDK loads after the framework has already hydrated

***

## 7. Best practices & troubleshooting

* **Keep it fast** – The SDK is delivered from our global CDN and is heavily cached. Still, monitor Web Vitals to ensure no regressions.
* **Avoid flicker** – In both modes the SDK temporarily sets `body{opacity:0}`. This usually lasts less than 50 ms, but audit on slow connections.
* **Test first** – Roll out the integration to a staging environment before production.
* **Need help?** – Reach out at [support@pagent.ai](mailto:support@pagent.ai).

By following these steps you will have pagent running on your site, ready to serve experiments and personalized content from the moment your users land.
