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

# Tag Manager Integration

> Deploy the Permutive JavaScript SDK via Google Tag Manager, Tealium, and Adobe Launch

This guide covers deploying the Permutive SDK through popular tag management systems.

<CardGroup cols={3}>
  <Card title="Google Tag Manager" href="#google-tag-manager" icon="google" />

  <Card title="Tealium" href="#tealium" icon="tag" />

  <Card title="Adobe Launch" href="#adobe-launch" icon="adobe" />
</CardGroup>

## Overview

When deploying via tag manager:

* **High priority execution** - Permutive should load before ad tags
* **Data layer integration** - Pass page properties from your data layer
* **Consistent deployment** - Use variables for credentials and properties

## Google Tag Manager

### Step 1: Create Permutive SDK Tag

1. Go to **Tags > New**
2. Click **Tag Configuration > Custom HTML**
3. Name it "Permutive SDK"
4. Add the SDK code:

```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,"{{Permutive API Key}}","{{Permutive Workspace ID}}",{});
</script>
<script async src="https://{{Permutive Organization ID}}.edge.permutive.app/{{Permutive Workspace ID}}-web.js"></script>
```

### Step 2: Create Credential Variables

1. Go to **Variables > User-Defined Variables > New**
2. Create a **Constant** variable for API Key:
   * Name: `Permutive API Key`
   * Value: Your API key
3. Create a **Constant** variable for Workspace ID:
   * Name: `Permutive Workspace ID`
   * Value: Your workspace ID

### Step 3: Set Up Trigger

1. Under the tag, click **Triggering**
2. Select **All Pages** trigger
3. Click **Advanced Settings > Tag Firing Options**
4. Set **Tag firing priority** to `9999` (highest priority)

### Step 4: Create Web Addon Tag

1. Create another Custom HTML tag named "Permutive Web Addon"
2. Add the web addon code:

```html theme={"dark"}
<script>
  permutive.addon('web', {
    page: {
      type: '{{Page Type}}',
      article: {
        title: '{{Page Title}}',
        categories: {{Page Categories}},
        authors: {{Page Authors}}
      }
    }
  });
</script>
```

3. Set trigger to **All Pages**
4. Set **Tag Sequencing** to fire after "Permutive SDK" tag

### Step 5: Create Data Layer Variables

Create variables to read from your data layer:

1. **Page Type** (Data Layer Variable)
   * Variable Name: `page.type`

2. **Page Title** (Data Layer Variable)
   * Variable Name: `page.title`
   * Or use built-in `{{Page Title}}`

3. **Page Categories** (Custom JavaScript Variable)
   ```javascript theme={"dark"}
   function() {
     var dl = window.dataLayer || [];
     for (var i = 0; i < dl.length; i++) {
       if (dl[i].page && dl[i].page.categories) {
         return dl[i].page.categories;
       }
     }
     return [];
   }
   ```

### Step 6: Data Layer Setup

On your website, push data to the data layer before GTM loads:

```html theme={"dark"}
<script>
  window.dataLayer = window.dataLayer || [];
  dataLayer.push({
    page: {
      type: 'article',
      title: 'Article Title',
      categories: ['news', 'technology'],
      authors: ['Jane Smith']
    }
  });
</script>
<!-- GTM Container -->
```

### Complete GTM Example

**Tag 1: Permutive SDK**

```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,"{{Permutive API Key}}","{{Permutive Workspace ID}}",{});
</script>
<script async src="https://{{Permutive Organization ID}}.edge.permutive.app/{{Permutive Workspace ID}}-web.js"></script>
```

* Trigger: All Pages
* Priority: 9999

**Tag 2: Permutive Web Addon**

```html theme={"dark"}
<script>
  (function() {
    var pageType = {{DL - Page Type}} || 'page';
    var pageTitle = {{Page Title}};
    var pageCategories = {{DL - Page Categories}} || [];

    permutive.addon('web', {
      page: {
        type: pageType,
        article: pageType === 'article' ? {
          title: pageTitle,
          categories: pageCategories
        } : undefined
      }
    });
  })();
</script>
```

* Trigger: All Pages
* Tag Sequencing: After "Permutive SDK"

## Tealium

### Step 1: Create JavaScript Code Extension

1. Go to **Extensions > Add Extension**
2. Select **JavaScript Code**
3. Set **Scope** to **Pre Loader** (runs before all tags)
4. Add the SDK code:

```javascript theme={"dark"}
// Permutive SDK Loader
!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,b["permutive_api_key"],b["permutive_workspace_id"],{});

// Load SDK
(function() {
  var script = document.createElement('script');
  script.src = 'https://' + b["permutive_organization_id"] + '.edge.permutive.app/' + b["permutive_workspace_id"] + '-web.js';
  script.async = true;
  document.head.appendChild(script);
})();
```

### Step 2: Set Up Data Layer Variables

In Tealium, map your data layer to variables:

* `permutive_api_key` → Your public API key
* `permutive_workspace_id` → Your workspace ID
* `permutive_organization_id` → Your organization ID
* `page_type` → Page type
* `page_title` → Page title
* `page_categories` → Categories array

### Step 3: Create Web Addon Extension

Add another JavaScript Code extension with **All Tags** scope:

```javascript theme={"dark"}
// Permutive Web Addon
permutive.addon('web', {
  page: {
    type: b["page_type"] || 'page',
    article: {
      title: b["page_title"],
      categories: b["page_categories"] || []
    }
  }
});
```

### Step 4: Configure Execution Order

1. Set the SDK loader extension order to **1** (first)
2. Set the web addon extension order to **2** (second)

## Adobe Launch

### Step 1: Create Core Extension Action

1. Go to **Rules > Add Rule**
2. Name it "Permutive SDK"
3. Under **Events**, add:
   * Extension: Core
   * Event Type: Library Loaded (Page Top)

### Step 2: Add SDK Action

1. Under **Actions**, click **Add**
2. Select:
   * Extension: Core
   * Action Type: Custom Code
   * Language: JavaScript
3. Check **Execute globally**
4. Add the SDK code:

```javascript theme={"dark"}
// Permutive SDK
!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,_satellite.getVar('Permutive API Key'),_satellite.getVar('Permutive Workspace ID'),{});

// Load SDK
(function() {
  var script = document.createElement('script');
  script.src = 'https://' + _satellite.getVar('Permutive Organization ID') + '.edge.permutive.app/' + _satellite.getVar('Permutive Workspace ID') + '-web.js';
  script.async = true;
  document.head.appendChild(script);
})();
```

### Step 3: Create Data Elements

1. Go to **Data Elements > Add Data Element**
2. Create these data elements:
   * `Permutive API Key` (Constant)
   * `Permutive Workspace ID` (Constant)
   * `Permutive Organization ID` (Constant)
   * `Page Type` (JavaScript Variable or Custom Code)
   * `Page Categories` (JavaScript Variable or Custom Code)

### Step 4: Create Web Addon Rule

1. Create a new rule "Permutive Web Addon"
2. Event: DOM Ready
3. Add Custom Code action:

```javascript theme={"dark"}
permutive.addon('web', {
  page: {
    type: _satellite.getVar('Page Type') || 'page',
    article: {
      title: document.title,
      categories: _satellite.getVar('Page Categories') || []
    }
  }
});
```

### Step 5: Set Rule Order

1. Set "Permutive SDK" rule order to **1**
2. Set "Permutive Web Addon" rule order to **10**

## Data Layer Best Practices

### Standardize Your Data Layer

Use consistent property names across your site:

```javascript theme={"dark"}
// Recommended data layer structure
window.dataLayer = window.dataLayer || [];
dataLayer.push({
  event: 'pageview',
  page: {
    type: 'article',        // article, homepage, section, video
    title: 'Page Title',
    categories: ['cat1', 'cat2'],
    tags: ['tag1', 'tag2'],
    authors: ['Author Name']
  },
  user: {
    isLoggedIn: true,
    hashedEmail: 'abc123...'  // SHA-256 hashed
  }
});
```

### Handle Identity in Tag Manager

```javascript theme={"dark"}
// In a separate tag, after SDK loads
if (dataLayer) {
  for (var i = 0; i < dataLayer.length; i++) {
    var data = dataLayer[i];
    if (data.user && data.user.hashedEmail) {
      permutive.identify([
        { tag: 'email_sha256', id: data.user.hashedEmail }
      ]);
      break;
    }
  }
}
```

## Troubleshooting Tag Manager Deployments

<AccordionGroup>
  <Accordion title="Tags firing in wrong order">
    **Problem:** Web addon fires before SDK loads.

    **Solutions:**

    * Use tag sequencing/ordering features
    * Set SDK tag priority to highest (e.g., 9999)
    * Use `permutive.ready()` in dependent tags
  </Accordion>

  <Accordion title="Variables not resolving">
    **Problem:** Data layer variables return undefined.

    **Solutions:**

    * Verify data layer is populated before GTM loads
    * Check variable names match exactly
    * Use default values: `{{Variable}} || 'default'`
    * Debug with GTM Preview mode
  </Accordion>

  <Accordion title="SDK not loading consistently">
    **Problem:** SDK sometimes loads, sometimes doesn't.

    **Solutions:**

    * Check trigger conditions
    * Verify no JavaScript errors blocking execution
    * Ensure async script loading works in your environment
    * Test with tag manager debug/preview mode
  </Accordion>

  <Accordion title="Consent not working with tag manager">
    **Problem:** Events not tracking with consent management.

    **Solution:** Create a consent tag that fires before web addon:

    ```javascript theme={"dark"}
    // Consent Tag (fire when CMP grants consent)
    permutive.consent({ opt_in: true, token: 'consent_token' });
    ```

    Then use tag sequencing to fire web addon after consent.
  </Accordion>
</AccordionGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Use Variables for Credentials">
    Never hardcode credentials directly in tags. Use tag manager variables for easy updates across environments.
  </Accordion>

  <Accordion title="Test in Preview/Debug Mode">
    Always test tag firing order and variable values in the tag manager's preview mode before publishing.
  </Accordion>

  <Accordion title="Document Your Setup">
    Keep notes on:

    * Tag names and purposes
    * Variable mappings
    * Data layer requirements
    * Firing order dependencies
  </Accordion>

  <Accordion title="Version Control">
    Use tag manager's versioning features and maintain a changelog of deployments.
  </Accordion>
</AccordionGroup>

## Related Documentation

<CardGroup cols={2}>
  <Card title="Installation" icon="download" href="/sdks/web/javascript-sdk/getting-started/installation">
    All installation methods
  </Card>

  <Card title="Initialization" icon="gear" href="/sdks/web/javascript-sdk/getting-started/initialization">
    Configuration options
  </Card>

  <Card title="Verification" icon="circle-check" href="/sdks/web/javascript-sdk/getting-started/verification">
    Verify your integration
  </Card>

  <Card title="Consent" icon="shield-check" href="/sdks/web/javascript-sdk/core-concepts/consent-management">
    Consent with tag managers
  </Card>
</CardGroup>
