# Consent Management in JavaScript SDK

<p>This guide explains the consent management functionality and the various consent tracking approaches supported by the JavaScript SDK.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="overview">Overview</h2><p>The JavaScript SDK supports RudderStack&rsquo;s <a href="https://www.rudderstack.com/docs/data-governance/consent-management/" >consent management</a> functionality and lets you manage data sent to downstream destinations based on user consent. This feature is crucial for respecting user privacy preferences and complying with data protection regulations.</p>
<p>With this functionality, you can:</p>
<ul>
<li>Seamlessly integrate with popular consent management providers like <a href="https://www.rudderstack.com/docs/data-governance/consent-management/onetrust/javascript/" >OneTrust</a>, <a href="https://www.rudderstack.com/docs/data-governance/consent-management/ketch/" >Ketch</a>, and <a href="https://www.rudderstack.com/docs/data-governance/consent-management/iubenda/" >iubenda</a>. You can also set up a <a href="https://www.rudderstack.com/docs/data-governance/consent-management/custom-consent-manager/" >custom consent management provider</a>.</li>
<li>Configure consent settings for multiple providers for your web source.</li>
<li>Unlock advanced use cases like <a href="#pre-consent-user-tracking" >pre-consent user tracking</a> where you can track user activity and control the SDK&rsquo;s behavior before and after the user provides their consent.</li>
</ul>
<p>See <a href="https://www.rudderstack.com/docs/data-governance/consent-management/overview/#consent-filtering-requirements" >Consent filtering requirements</a> for more information on the consent filtering settings at destination and event payload levels.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="consent-management-approaches">Consent management approaches</h2><p>There are two primary approaches to implementing consent management with the RudderStack JavaScript SDK:</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="post-consent-user-tracking">Post-consent user tracking</h3><p>Post-consent user tracking is the most common implementation where you load the JavaScript SDK only after the user has provided consent. This approach is straightforward but has limitations:</p>
<ul>
<li>It ensures that no tracking occurs before consent is given</li>
<li>You cannot control SDK behavior before consent is provided</li>
<li>It may result in loss of some initial user activity data</li>
</ul>
<p>See the <a href="https://www.rudderstack.com/docs/data-governance/consent-management/onetrust/javascript/#post-consent-user-tracking" >OneTrust post-consent user tracking setup</a> for a sample implementation.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="pre-consent-user-tracking">Pre-consent user tracking</h3><p>Pre-consent user tracking allows you to track some user activity and control SDK behavior both <a href="#the-preconsent-object" >before</a> and <a href="#consent-api" >after</a> the user provides consent. This approach offers more flexibility because of the following reasons:</p>
<ul>
<li>It minimizes data loss related to attribution, acquisition, and the overall user journey</li>
<li>You can choose to track users as fully anonymous, or persist only the information you need, for example, their sessions or the <code>anonymousId</code> identifier</li>
<li>It allows for a more nuanced approach to data collection based on consent status</li>
<li>There is no particular restriction on the loading order of the SDKs</li>
</ul>
<p>See the <a href="https://www.rudderstack.com/docs/data-governance/consent-management/onetrust/javascript/#pre-consent-user-tracking" >OneTrust pre-consent user tracking setup</a> for a sample implementation.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p>The presence of consent management object in the event&rsquo;s context (<code>context.consentManagement</code>) helps you differentiate between the pre- and post-consent events.</p>
<p>RudderStack does not add any other extra property to differentiate these events.</p>
</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="key-components-of-pre-consent-user-tracking">Key components of pre-consent user tracking</h2><p>This section explains the key components of pre-consent user tracking in the JavaScript SDK.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="the-preconsent-object">The <code>preConsent</code> object</h3><p>You can use the <code>preConsent</code> object while loading the JavaScript SDK to enable pre-consent mode and define the SDK&rsquo;s <a href="#events-delivery-strategy" >events delivery behavior</a>. Use the <a href="#storage-in-pre-consent-mode" ><code>storage</code> load option</a> to define what the SDK persists before the user provides consent.</p>
<ol>
<li>Pass the consent management platform&rsquo;s information in the <code>consentManagement</code> object as a <code>load</code> API option.</li>
<li>Add the <code>storage</code> and <code>preConsent</code> objects, as shown:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  consentManagement: {
    enabled: true,
    provider: &#34;oneTrust&#34; / &#34;ketch&#34; / &#34;iubenda&#34; / &#34;custom&#34;
  },
  storage: { // Optional; defines what the SDK persists
    entries: {
      anonymousId: {
        type: &#34;cookieStorage&#34;
      }
    }
  },
  preConsent: {
    enabled: true, // false by default
    storage: { // Optional
      enabled: true, // false by default; applies the storage option before consent
    },
    events: { // Optional
      delivery: &#34;immediate&#34; / &#34;buffer&#34;, // Default is &#34;immediate&#34;
    },
  },
  ...
  // Other load options
});</code></pre></div>
</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">If you set <code>preConsent.enabled</code> to <code>true</code>, the JavaScript SDK does <strong>not</strong> load the device mode integrations.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="storage-in-pre-consent-mode">Storage in pre-consent mode</h4><p>Set <code>preConsent.storage.enabled</code> to <code>true</code> to apply the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#storage" ><code>storage</code> load option</a> during the pre-consent phase. The same option then decides what the SDK persists both before and after the user provides consent, and only the fallback differs: while pre-consent mode is active, the SDK persists an entry <strong>only</strong> if you explicitly set a storage type for it, either through <code>storage.entries.&lt;entry&gt;.type</code> or the global <code>storage.type</code>. The SDK does not persist any entry you leave unconfigured.</p>
<p>Once you invoke the <a href="#consent-api" ><code>consent</code> API</a>, the SDK reverts to its usual default (<code>cookieStorage</code>) for the entries you have not configured.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text"><p><code>preConsent.storage.enabled</code> is <code>false</code> by default, so your existing configuration is unaffected until you set it. Without it, the deprecated <a href="#cookie-storage-strategy" ><code>preConsent.storage.strategy</code></a> continues to decide what the SDK persists, and if you set neither, the SDK persists nothing before consent.</p>
<p>If you set both, <code>preConsent.storage.enabled</code> takes precedence and the SDK ignores <code>strategy</code>.</p>
</div>
  </div>
</blockquote>

</html>
<p>You can set a storage type for the following entries: <code>userId</code>, <code>userTraits</code>, <code>anonymousId</code>, <code>groupId</code>, <code>groupTraits</code>, <code>initialReferrer</code>, <code>initialReferringDomain</code>, <code>sessionInfo</code>, and <code>authToken</code>.</p>
<p>Each entry accepts <code>cookieStorage</code>, <code>localStorage</code>, <code>sessionStorage</code>, <code>memoryStorage</code>, or <code>none</code>. See <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/persistent-data-storage/#set-storage-type" >Configure Persistent Data Storage in JavaScript SDK</a> for what each value means.</p>
<p>The following example persists both the anonymous ID and the session information before consent, and buffers the events until the user consents:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  consentManagement: {
    enabled: true,
    provider: &#34;oneTrust&#34;
  },
  storage: {
    entries: {
      anonymousId: {
        type: &#34;cookieStorage&#34;
      },
      sessionInfo: {
        type: &#34;cookieStorage&#34;
      }
    }
  },
  preConsent: {
    enabled: true,
    storage: {
      enabled: true
    },
    events: {
      delivery: &#34;buffer&#34;
    }
  }
  // Other load options
});</code></pre></div>
</div>
<p>Because each entry is configured on its own, you can mix and match them, for example, persist the anonymous ID in a cookie, keep the session information in memory, and store nothing else.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="cookie-storage-strategy">Cookie storage strategy</h4>
<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text"><p><code>preConsent.storage.strategy</code> is <strong>deprecated</strong> and will be removed in the next major version. Use the <a href="#storage-in-pre-consent-mode" ><code>storage</code> load option</a> instead.</p>
<p>The option still works exactly as before, but the SDK logs a deprecation warning when you set it. While it is in effect, the SDK does not persist the entries that the strategy excludes, even if you configure a storage type for them.</p>
<p>If you set both <code>strategy</code> and <code>preConsent.storage.enabled</code>, the latter takes precedence and the SDK ignores <code>strategy</code>.</p>
</div>
  </div>
</blockquote>
<p>The SDK stores information in the pre-consent mode based on the following cookie storage strategies:</p>
<table>
  <thead>
      <tr>
          <th>Value</th>
          <th><div>Description</div></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>none</code></td>
          <td>Fully anonymous tracking where RudderStack does not store any cookies.  <br /><br />For this value, note that:<br /><br /><ul><li>Each event contains a new <code>anonymousId</code>.</li><li>Session tracking is <strong>not available</strong>. Events sent before consent do not contain a <code>sessionId</code>.</li><li>The SDK does not persist any data from the previous API calls, that is, <code>userId</code>, <code>groupId</code>, <code>traits</code>, etc. are not included in the future events.</li></ul></td>
      </tr>
      <tr>
          <td><code>session</code></td>
          <td>Fully anonymous tracking where RudderStack stores only the session tracking cookie (<a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/session-tracking/manual-session-tracking/" >manual</a> or <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/session-tracking/#automatic-session-tracking" >automatic</a>), if it is active. <br /><br />For this value, note that:<br /><br /><ul><li>Each event contains a new <code>anonymousId</code>.</li><li>The SDK does not persist any data from the previous API calls, that is, <code>userId</code>, <code>groupId</code>, <code>traits</code>, etc. are not included in the future events.</li></ul></td>
      </tr>
      <tr>
          <td><code>anonymousId</code></td>
          <td>RudderStack persists only the anonymous ID (<code>anonymousId</code>). <br /><br />For this value, note that:<br /><br /><ul><li>Session tracking is <strong>not available</strong>. Events sent before consent do not contain a <code>sessionId</code>.</li><li>The SDK does not persist any data from the previous API calls, that is, <code>userId</code>, <code>groupId</code>, <code>traits</code>, etc. are not included in the future events.</li></ul></td>
      </tr>
  </tbody>
</table>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="migrate-from-the-cookie-storage-strategy">Migrate from the cookie storage strategy</h4><p>Replace <code>strategy</code> with <code>enabled: true</code> in the <code>preConsent.storage</code> object, then move the configuration to the <a href="#storage-in-pre-consent-mode" ><code>storage</code> load option</a>:</p>
<table>
  <thead>
      <tr>
          <th>Deprecated strategy</th>
          <th>Equivalent configuration</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>strategy: &quot;none&quot;</code></td>
          <td>Omit <code>preConsent.storage</code> entirely. This is the default behavior.</td>
      </tr>
      <tr>
          <td><code>strategy: &quot;session&quot;</code></td>
          <td>Set <code>preConsent.storage.enabled</code> to <code>true</code> and set <code>storage: { entries: { sessionInfo: { type: &quot;cookieStorage&quot; } } }</code></td>
      </tr>
      <tr>
          <td><code>strategy: &quot;anonymousId&quot;</code></td>
          <td>Set <code>preConsent.storage.enabled</code> to <code>true</code> and set <code>storage: { entries: { anonymousId: { type: &quot;cookieStorage&quot; } } }</code></td>
      </tr>
  </tbody>
</table>

<blockquote class="warning">
  <div class="tip-quote">
    
    <div class="tip-text">Set <code>preConsent.storage.enabled</code> to <code>true</code> when you remove <code>strategy</code>. If you remove <code>strategy</code> without it, the SDK persists nothing before consent.</div>
  </div>
</blockquote>
<p>For example, the following configuration persists only the session information before consent:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Before
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  consentManagement: {
    enabled: true,
    provider: &#34;oneTrust&#34;
  },
  preConsent: {
    enabled: true,
    storage: {
      strategy: &#34;session&#34;
    }
  }
  // Other load options
});</code></pre></div>
</div>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// After
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  consentManagement: {
    enabled: true,
    provider: &#34;oneTrust&#34;
  },
  storage: {
    entries: {
      sessionInfo: {
        type: &#34;cookieStorage&#34;
      }
    }
  },
  preConsent: {
    enabled: true,
    storage: {
      enabled: true
    }
  }
  // Other load options
});</code></pre></div>
</div>
<p>The <code>storage</code> option is not limited to the three strategies. You can persist any combination of <a href="#storage-in-pre-consent-mode" >entries</a> and pick a different storage type for each one.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="session-tracking-in-pre-consent-mode">Session tracking in pre-consent mode</h4><p>To retain session tracking during the pre-consent phase, set a storage type for the <code>sessionInfo</code> entry. Unless you also persist <code>anonymousId</code>, the SDK generates a new <code>anonymousId</code> per event until consent is granted.</p>
<p>If you do not persist <code>sessionInfo</code> but still want to group pre-consent events into a session, use the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/custom-context/" ><code>setCustomContext</code></a> API. Custom context is in-memory only and does not write any cookies or storage, so it is compatible with all pre-consent storage configurations.</p>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">Since custom context is in-memory only, the identifier resets on page reload and groups events within a single page load.</div>
  </div>
</blockquote>

</html>
<p>For example, generate a session-like identifier and attach it to all events:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// Before consent: attach a custom session identifier
rudderanalytics.setCustomContext({
  preConsentSessionId: crypto.randomUUID()
});</code></pre></div>
</div>
<p>After the user grants consent and native session tracking resumes, clear the custom context:</p>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">// After consent is granted
rudderanalytics.clearCustomContext();</code></pre></div>
</div>
<!-- end-chunk -->
<!-- begin-chunk -->
<h4 id="events-delivery-strategy">Events delivery strategy</h4>
<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">As the SDK does not load any device mode destinations in pre-consent mode, you can control the events delivery strategy for the cloud mode destinations only.</div>
  </div>
</blockquote>

</html>
<p>The SDK delivers events in the pre-consent mode based on the following values:</p>
<table>
  <thead>
      <tr>
          <th>Value</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>immediate</code></td>
          <td>RudderStack sends the events to the RudderStack backend (data plane) immediately as they occur.</td>
      </tr>
      <tr>
          <td><code>buffer</code></td>
          <td>The SDK buffers the events in the local storage. You can use the <a href="#consent-api" ><code>consent</code> API</a> to decide what to do with these buffered events. <br /><br />This option works with any <a href="#storage-in-pre-consent-mode" >pre-consent storage configuration</a>.</td>
      </tr>
  </tbody>
</table>
<p>The SDK decides the delivery for preload events (events instrumented to the SDK before it is loaded), <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/detecting-adblocked-pages/" >ad-blocked page view</a> events, and <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/supported-api/#query-string-api" >Query string API</a> events, based on the above options (<code>immediate</code>/<code>buffer</code>) set in the pre-consent mode.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="consent-api">The <code>consent</code> API</h3>

<p>You can invoke the JavaScript SDK&rsquo;s <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/supported-api/#consent-api" ><code>consent</code> API</a> once the user consent is available. The SDK then comes out of the pre-consent mode and resumes normal functioning.</p>
<p>A sample implementation for a <a href="https://www.rudderstack.com/docs/data-governance/consent-management/custom-consent-manager/javascript/" >custom provider</a> is shown below:</p>
<div class="rs-code">
  <div class="rs-code__head">html<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-html" data-lang="html">&lt;script type = &#34;text/javascript&#34;&gt;
  // consent provider callback
  function ConsentManagerWrapper() { /// Pseudo name
    if (window.isConsented()) { // Pseudo name

      // Pass the allowed and denied category IDs for custom setup
      rudderanalytics.consent({
        options: {
          trackConsent: true / false, // Optional; default is false
          consentManagement: {
            allowedConsentIds: [&#39;&lt;category_id_1&gt;&#39;,&#39;&lt;category_id_2&gt;&#39;,.....], // Required for Custom provider
            deniedConsentIds: [&#39;&lt;category_id_3&gt;&#39;,&#39;&lt;category_id_4&gt;&#39;,.....]
          }, // Required for Custom provider
          storage: {
            type: &#34;cookieStorage&#34;, // Other supported values are &#34;localStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
            entries: {
              userId: {
                type: &#34;localStorage&#34; // Other supported values are &#34;cookieStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
              },
              userTraits: {
                type: &#34;cookieStorage&#34; // Other supported values are &#34;localStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
              },
              sessionInfo: {
                type: &#34;cookieStorage&#34; // Other supported values are &#34;localStorage&#34;,&#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;
              }
            }
          }, // Optional
          integrations: IntegrationOpts, // Optional
          discardPreConsentEvents: true / false, // Optional; default is false
          sendPageEvent: true / false // Optional, default is false
        }
      });
    }
  } 
&lt;/script&gt;</code></pre></div>
</div>
<p>The <code>consent</code> API options are listed below:</p>
<table>
  <thead>
      <tr>
          <th>Parameter</th>
          <th>Type</th>
          <th>Description</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>trackConsent</code></td>
          <td>Boolean</td>
          <td>Determines if the SDK should send a <code>track</code> event with the name <code>Consent Management Interaction</code>. <br /><br /><strong>Default value</strong>: <code>false</code></td>
      </tr>
      <tr>
          <td><code>consentManagement</code></td>
          <td>Object</td>
          <td>Lets you pass the user consent data in case of a <a href="https://www.rudderstack.com/docs/data-governance/consent-management/custom-consent-manager/" >custom consent management provider</a>. The SDK <strong>requires</strong> the <code>allowedConsentIds</code> and <code>deniedConsentIds</code> fields in case of a <strong>Custom</strong> consent provider.</td>
      </tr>
      <tr>
          <td><code>storage</code></td>
          <td>Object</td>
          <td>Lets you configure the different storage-specific options like: <br /><br /><ul><li><a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/persistent-data-storage/#set-storage-type" ><code>storage.type</code></a>: Specify where the persisted data should be stored.</li><li><a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/persistent-data-storage/##set-storage-for-specific-information-type" ><code>storage.entries</code></a>: Lets you define storage for specific type of persisted user data.</li></ul></td>
      </tr>
      <tr>
          <td><code>integrations</code></td>
          <td>Object</td>
          <td>Instructs the SDK to filter the integrations before the consent filtering takes effect.</td>
      </tr>
      <tr>
          <td><code>discardPreConsentEvents</code></td>
          <td>Boolean</td>
          <td>Determines if the SDK should discard all the pre-consent events buffered previously. <br /><br /><strong>Default value</strong>: <code>false</code></td>
      </tr>
      <tr>
          <td><code>sendPageEvent</code></td>
          <td>Boolean</td>
          <td>Determines if the SDK should send a <code>page</code> event. <br /><br /><strong>Default value</strong>: <code>false</code></td>
      </tr>
  </tbody>
</table>
<p>The SDK does the following once you invoke the <code>consent</code> API:</p>
<ul>
<li>Loads the device mode integrations based on consent.</li>
<li>Fetches the consent information from the consent manager.</li>
<li>Stores persistent user information like <code>userId</code>, <code>anonymousId</code>, <code>traits</code>, etc. according to the specified <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/data-storage-cookies/persistent-data-storage/#set-storage-type" ><code>storage</code></a> option.</li>
<li>Discards or replays the buffered pre-consent events to the destinations based on the <code>discardPreconsentEvents</code> parameter.</li>
</ul>
<p>The SDK also sends any events received after the user gives consent to the destinations immediately.</p>

<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="set-different-pre-consent-and-post-consent-storage-options">Set different pre-consent and post-consent storage options</h2><p>You can configure different <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#storage" >storage options</a> for pre-consent and post-consent user tracking that let you:</p>
<ul>
<li>Ensure data is stored appropriately based on the consent status and reduce unnecessary data collection.</li>
<li>Maintain seamless user experience while respecting users&rsquo; privacy preferences.</li>
</ul>
<p>Follow these steps to set different storage options for pre-consent and post-consent user tracking:</p>
<ol>
<li>Configure the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#storage" >storage options</a> while loading the JavaScript SDK. These options define what the SDK persists <a href="#storage-in-pre-consent-mode" >before consent</a>.</li>
<li>Set <a href="#the-preconsent-object" ><code>preConsent.enabled</code></a> and <code>preConsent.storage.enabled</code> to <code>true</code>. You can also define the SDK&rsquo;s <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/consent-management/#events-delivery-strategy" >events delivery strategy</a> here.</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  storage: {
    encryption: {
      version: &#34;v3&#34; / &#34;legacy&#34;
    },
    entries: {
      sessionInfo: {
        type: &#34;cookieStorage&#34; // Other available options are &#34;localStorage&#34;, &#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;.
      }
    }
    // Other storage options
  },
  consentManagement: {
    enabled: true,
    provider: &#34;oneTrust&#34; / &#34;ketch&#34; / &#34;iubenda&#34; / &#34;custom&#34; // Specify your consent management provider
  },
  preConsent: {
    enabled: true,
    storage: { // Optional; applies the storage option before consent
      enabled: true // Optional; false by default
    },
    events: { // Optional; defines SDK&#39;s events delivery behavior
      delivery: &#34;buffer&#34; // Optional; other accepted value is &#34;immediate&#34;
    },
  },
  // Other load options
});</code></pre></div>
</div>
<p>In the above snippet, the SDK persists only the session information before consent, as <code>sessionInfo</code> is the only entry with a storage type.</p>
<ol start="3">
<li>Invoke the <code>consent</code> API <strong>after</strong> the user provides consent. You can also define the SDK&rsquo;s post-consent <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/load-js-sdk/#storage" >storage options</a> here.</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">rudderanalytics.consent({
  trackConsent: true,
  discardPreConsentEvents: true, // Optional; default value is false
  storage: {
    type: &#34;localStorage&#34; // Other available options are &#34;cookieStorage&#34;, &#34;sessionStorage&#34;, &#34;memoryStorage&#34;, and &#34;none&#34;.
  }
});</code></pre></div>
</div>

<html lang="en">
<blockquote class="info">
  <div class="tip-quote">
    
    <div class="tip-text">The storage options you pass to the <code>consent</code> API persist across its invocations. If you invoke the API again without any storage options, the SDK retains the storage configuration from the previous invocation.</div>
  </div>
</blockquote>

</html>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="integration-with-consent-management-platforms">Integration with consent management platforms</h2><p>RudderStack&rsquo;s JavaScript SDK integrates with various consent management platforms:</p>
<ul>
<li><a href="https://www.rudderstack.com/docs/data-governance/consent-management/onetrust/javascript/#set-up-website" >OneTrust</a></li>
<li><a href="https://www.rudderstack.com/docs/data-governance/consent-management/ketch/" >Ketch</a></li>
<li><a href="https://www.rudderstack.com/docs/data-governance/consent-management/iubenda/" >iubenda</a></li>
<li><a href="https://www.rudderstack.com/docs/data-governance/consent-management/custom-consent-manager/javascript/#setup" >Custom providers</a></li>
</ul>
<p>These integrations enable:</p>
<ul>
<li>Flexibility to use the consent management tool that best fits your needs</li>
<li>Seamless coordination between consent decisions and data collection</li>
<li>Compliance with privacy regulations across different jurisdictions</li>
</ul>
<p>For the Android (Kotlin) and iOS (Swift) SDKs, see <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/client-side-features/consent-management/" >Consent Management in Mobile SDKs</a>.</p>
<br />

