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

# Initialization

> Configure and initialize the Permutive JavaScript SDK

The SDK initializes automatically when the `live.js` script loads. Configuration options are passed in the loader script and control SDK behavior.

## Basic Initialization

The standard initialization passes your credentials and optional configuration:

```html theme={"dark"}
<script>
  !function(e,o,n,i){if(!e){e=e||{},window.permutive=e,e.q=[];var t=function(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(e){return(e^(window.crypto||window.msCrypto).getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)})};e.config=i||{},e.config.apiKey=o,e.config.workspaceId=n,e.config.environment=e.config.environment||"production",(window.crypto||window.msCrypto)&&(e.config.viewId=t());for(var g=["addon","identify","track","trigger","query","segment","segments","ready","on","once","user","consent"],r=0;r<g.length;r++){var w=g[r];e[w]=function(o){return function(){var n=Array.prototype.slice.call(arguments,0);e.q.push({functionName:o,arguments:n})}}(w)}}}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>",{});
</script>
<script async src="https://<ORGANIZATION_ID>.edge.permutive.app/<WORKSPACE_ID>-web.js"></script>
```

## Configuration Options

Pass configuration options as the fourth argument to the loader function:

```javascript theme={"dark"}
!function(e,o,n,i){/* ... */}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>", {
  // Configuration options here
  consentRequired: false,
  loggingEnabled: false
});
```

### Available Options

| Option            | Type    | Default        | Description                                                                  |
| ----------------- | ------- | -------------- | ---------------------------------------------------------------------------- |
| `consentRequired` | boolean | `false`        | When `true`, SDK waits for consent before tracking                           |
| `loggingEnabled`  | boolean | `false`        | Enable console logging (also enabled via `?__permutive.loggingEnabled=true`) |
| `cookieDomain`    | string  | Current domain | Domain for the Permutive cookie                                              |
| `requestTimeout`  | number  | `5000`         | API request timeout in milliseconds                                          |

### Consent-Required Mode

When `consentRequired: true`, the SDK will not track any events until consent is granted:

```html theme={"dark"}
<script>
  !function(e,o,n,i){/* ... */}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>", {
    consentRequired: true
  });
</script>
<script async src="https://<ORGANIZATION_ID>.edge.permutive.app/<WORKSPACE_ID>-web.js"></script>

<script>
  // SDK is loaded but not tracking
  // Events will be ignored until consent is granted

  // When user consents:
  permutive.consent({ opt_in: true, token: '<CONSENT_TOKEN>' });

  // Now initialize the web addon
  permutive.addon('web', {
    page: { type: 'article' }
  });
</script>
```

<Warning>
  With `consentRequired: true`, all tracking is blocked until `permutive.consent()` is called with `opt_in: true`. Events called before consent are not queued - they are discarded.
</Warning>

## Web Addon Configuration

The web addon is initialized separately and handles automatic tracking. Call it after the SDK loads:

```javascript theme={"dark"}
permutive.addon('web', {
  page: {
    type: 'article',
    article: {
      title: 'Article Title',
      categories: ['news', 'technology'],
      authors: ['John Smith'],
      publishedAt: '2024-01-15T10:00:00Z'
    }
  }
});
```

### Web Addon Options

| Option          | Type   | Description                                                    |
| --------------- | ------ | -------------------------------------------------------------- |
| `page`          | object | Custom page properties to include in Pageview events           |
| `page.type`     | string | Page type (e.g., 'article', 'homepage', 'section')             |
| `page.article`  | object | Article-specific metadata                                      |
| `page.video`    | object | Video-specific metadata                                        |
| `eventInterval` | number | Milliseconds between PageviewEngagement events (default: 5000) |
| `context`       | object | Override default context (title, URL, referrer)                |

### Page Property Examples

<Tabs>
  <Tab title="Article Page">
    ```javascript theme={"dark"}
    permutive.addon('web', {
      page: {
        type: 'article',
        article: {
          title: 'Breaking News: Tech Advances',
          id: 'article-123',
          categories: ['technology', 'business'],
          tags: ['AI', 'startups', 'innovation'],
          authors: ['Jane Smith', 'John Doe'],
          publishedAt: '2024-01-15T10:00:00Z',
          modifiedAt: '2024-01-15T14:30:00Z',
          premium: true,
          wordCount: 1500
        }
      }
    });
    ```
  </Tab>

  <Tab title="Homepage">
    ```javascript theme={"dark"}
    permutive.addon('web', {
      page: {
        type: 'homepage'
      }
    });
    ```
  </Tab>

  <Tab title="Section Page">
    ```javascript theme={"dark"}
    permutive.addon('web', {
      page: {
        type: 'section',
        section: {
          name: 'Technology',
          path: '/technology'
        }
      }
    });
    ```
  </Tab>

  <Tab title="Video Page">
    ```javascript theme={"dark"}
    permutive.addon('web', {
      page: {
        type: 'video',
        video: {
          title: 'Product Demo',
          id: 'video-456',
          duration: 180,
          categories: ['product', 'tutorial']
        }
      }
    });
    ```
  </Tab>
</Tabs>

## Waiting for SDK Ready

Use `permutive.ready()` to execute code after the SDK initializes:

```javascript theme={"dark"}
// Wait for SDK initialization
permutive.ready(function() {
  console.log('Permutive SDK is ready');

  // Safe to access cohorts, etc.
  permutive.segments(function(segments) {
    console.log('User cohorts:', segments);
  });
});
```

### Ready Stages

The `ready()` method accepts an optional stage parameter:

```javascript theme={"dark"}
// Default: Wait for basic initialization
permutive.ready(function() {
  // SDK initialized, can track events
}, 'initialised');

// Wait for real-time cohort data
permutive.ready(function() {
  // Real-time cohort data is available
  permutive.segments(function(segments) {
    // segments array is populated
  });
}, 'realtime');
```

| Stage         | When Fires                               |
| ------------- | ---------------------------------------- |
| `initialised` | SDK has loaded and initialized (default) |
| `realtime`    | Real-time cohort data has been processed |

## Initialization Order

For optimal performance, follow this initialization order:

<Steps>
  <Step title="Loader Script">
    The inline loader script runs first, creating the queue and stub methods.
  </Step>

  <Step title="Consent (if required)">
    If using `consentRequired: true`, call `permutive.consent()` after obtaining user consent.
  </Step>

  <Step title="Identify (if available)">
    If you have user identity (e.g., logged-in user), call `permutive.identify()` early.
  </Step>

  <Step title="Web Addon">
    Initialize the web addon to start tracking pageviews and engagement.
  </Step>

  <Step title="Other Addons">
    Initialize other addons (DFP, Prebid, etc.) after the web addon.
  </Step>
</Steps>

### Example: Complete Initialization

```html theme={"dark"}
<!DOCTYPE html>
<html>
<head>
  <!-- 1. SDK Loader -->
  <script>
    !function(e,o,n,i){if(!e){e=e||{},window.permutive=e,e.q=[];var t=function(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(e){return(e^(window.crypto||window.msCrypto).getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)})};e.config=i||{},e.config.apiKey=o,e.config.workspaceId=n,e.config.environment=e.config.environment||"production",(window.crypto||window.msCrypto)&&(e.config.viewId=t());for(var g=["addon","identify","track","trigger","query","segment","segments","ready","on","once","user","consent"],r=0;r<g.length;r++){var w=g[r];e[w]=function(o){return function(){var n=Array.prototype.slice.call(arguments,0);e.q.push({functionName:o,arguments:n})}}(w)}}}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>",{});
  </script>
  <script async src="https://<ORGANIZATION_ID>.edge.permutive.app/<WORKSPACE_ID>-web.js"></script>

  <!-- 2. Set identity if available -->
  <script>
    if (window.userEmail) {
      permutive.identify([
        { tag: 'email_sha256', id: hashSHA256(window.userEmail) }
      ]);
    }
  </script>

  <!-- 3. Initialize web addon -->
  <script>
    permutive.addon('web', {
      page: {
        type: 'article',
        article: {
          title: document.title,
          categories: window.pageCategories || []
        }
      }
    });
  </script>
</head>
<body>
  <!-- Page content -->
</body>
</html>
```

## Cookie Configuration

The SDK uses a first-party cookie to persist user identity. Configure the cookie domain for cross-subdomain tracking:

```javascript theme={"dark"}
!function(e,o,n,i){/* ... */}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>", {
  cookieDomain: '.example.com'  // Shared across subdomains
});
```

<Info>
  Set `cookieDomain` to your root domain (with leading dot) to track users across subdomains like `www.example.com` and `blog.example.com`.
</Info>

## Environment Configuration

For testing environments, you may want different configurations:

```javascript theme={"dark"}
var config = {
  loggingEnabled: window.location.hostname !== 'www.example.com'
};

!function(e,o,n,i){/* ... */}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>", config);
```

## Troubleshooting Initialization

<AccordionGroup>
  <Accordion title="SDK not initializing">
    **Problem:** No console messages, `permutive.ready()` callback never fires.

    **Solutions:**

    * Check that API key and workspace ID are correct
    * Verify `live.js` is loading (check Network tab)
    * Look for errors in the console
    * Ensure the loader script runs before `live.js`
  </Accordion>

  <Accordion title="Events not tracking with consentRequired">
    **Problem:** Events are called but nothing appears in dashboard.

    **Cause:** `consentRequired: true` but `consent()` was not called.

    **Solution:** Call `permutive.consent({ opt_in: true, token: '...' })` after obtaining user consent.
  </Accordion>

  <Accordion title="Web addon not tracking pageviews">
    **Problem:** SDK initializes but no Pageview events.

    **Solutions:**

    * Verify `permutive.addon('web', {...})` is called
    * Check that consent has been granted (if `consentRequired: true`)
    * Enable debug mode to see detailed logging
  </Accordion>

  <Accordion title="ready() callback fires before data is available">
    **Problem:** Calling `segments()` in `ready()` callback returns empty array.

    **Solution:** Use the `'realtime'` stage:

    ```javascript theme={"dark"}
    permutive.ready(function() {
      permutive.segments(function(s) {
        console.log(s);  // Now populated
      });
    }, 'realtime');
    ```
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Verification" icon="circle-check" href="/sdks/web/javascript-sdk/getting-started/verification">
    Verify your integration is working
  </Card>

  <Card title="Pageview Tracking" icon="file" href="/sdks/web/javascript-sdk/features/pageview-tracking">
    Customize pageview tracking
  </Card>
</CardGroup>
