How to Clear Local & Session Storage on Tracking Opt-Out (Beyond Cookies)

Edited

This guide explains why blocking cookies and scripts alone may not be sufficient to fully honor a user's opt-out request, and how to clear browser storage used by analytics and session replay tools when consent is withdrawn.

FullStory is used throughout this article as an illustrative example. The same principles and approach apply to any tool that writes data to localStorage or sessionStorage.

This article is not intended to be a full implementation guide for any specific platform. It focuses on the browser storage clearing pattern and illustrates one common implementation method using Google Tag Manager.

Cookies Are Not the Whole Picture

Most consent enforcement strategies focus on cookies. Cookie auto-blocking, script blocking, and tag manager consent triggers are all designed primarily to prevent cookie-based tracking from occurring without consent.

However, many modern analytics and session replay tools also write data to the browser's localStorage and sessionStorage. These are separate browser storage mechanisms that are not affected by cookie-blocking logic. Auto-blocking a script URL or blocking a tag prevents the tool from loading on a fresh page load for opted-out users, but it does not remove data that the tool has already written to browser storage.

When a user opts out mid-session, the following gaps can exist even with script blocking in place:

  • The tool has already initialized and is actively recording the session

  • Session identifiers and metadata remain in localStorage or sessionStorage

  • The tool continues sending data until the page is reloaded or the browser is closed

Fully honoring an opt-out requires actively calling the tool's shutdown API and clearing its storage keys at the moment consent is withdrawn.

How This Differs from Script-Level Blocking

Script-level blocking and storage clearing serve different purposes and should be thought of as complementary, not interchangeable.

Script-level blocking prevents a tool from loading at all for users who are already opted out when the page loads. This is the correct mechanism for preventing initial execution.

Storage clearing addresses what happens after a tool has already loaded. It stops an active session, removes identifiers the tool has written to the browser, and ensures that a returning opted-out user does not have stale session data that could be picked back up if the tool is ever re-initialized.

Both layers are needed for a complete opt-out implementation.

When to Use This Configuration

This setup is most relevant for websites using an opt-out consent model, where analytics and session replay tools fire by default and must be stopped when a user actively withdraws consent.

It is also relevant for opt-in models where a user may have previously granted consent and is now withdrawing it, leaving residual storage data behind from prior sessions.

Step 1: Identify the Tool's Storage Keys and Shutdown API

Before implementing anything, you need two pieces of information about the tool you are targeting.

First, identify what storage keys the tool writes. Open the browser's developer tools, navigate to Application > Session Storage and Application > Local Storage, and look for keys associated with the tool. Common patterns include key prefixes tied to the tool's name or namespace, such as _fs_ and fs- for FullStory.

Second, locate the tool's shutdown or opt-out API in its developer documentation. Most session replay and analytics tools expose a method that stops active recording and data transmission when called. Examples include:

  • FullStory (v1.3.0 and older): FS.shutdown()

  • FullStory (v2.0 and newer): FS('shutdown')

  • Hotjar: hj('stateChange', 'opt_out_complete')

  • Microsoft Clarity: clarity('stop')

If a tool does not expose a shutdown API, storage clearing alone is still valuable, as it removes the session identifiers the tool would use to continue or resume tracking.

Step 2: Implement the Shutdown Logic

The core logic is a small JavaScript function that calls the tool's shutdown API and clears its storage keys. This function is platform-agnostic and can be deployed in several ways depending on how your site is built and where your tracking tools are loaded from.

The following example is written for FullStory. Adapt the shutdown call and key prefixes for your specific tool.

(function() {
  // Call the tool's native shutdown API
  if (typeof FS !== 'undefined' && typeof FS.shutdown === 'function') {
    FS.shutdown();
  }
  // Clear all matching keys from sessionStorage and localStorage
  ['sessionStorage', 'localStorage'].forEach(function(storageType) {
    Object.keys(window[storageType]).forEach(function(key) {
      if (
        key.indexOf('_fs_') === 0 ||
        key.indexOf('fs_') === 0 ||
        key.indexOf('fs-') === 0
      ) {
        window[storageType].removeItem(key);
      }
    });
  });
})();

The typeof check before calling the shutdown method ensures the function fails silently if the tool has not yet initialized, rather than throwing a JavaScript error.

Step 3: Wire the Logic to a Consent Change Event

The shutdown function needs to execute at the moment a user opts out. How you wire this depends on your implementation.

Via Google Tag Manager

Create a new Custom HTML tag containing the script above. Set the trigger to:

  • Trigger type: Custom Event

  • Event name: captainComplianceConsentUpdated

  • Add condition: the relevant Captain Compliance consent DLV equals false

For FullStory, which is classified as a Performance tool, the condition is CaptainPerformance equals false. Use the consent category that corresponds to how the tool is classified in your Captain Compliance banner configuration.

Via Application Code

For sites built on frameworks such as React, Vue, or Angular, the shutdown logic can be called directly from within the application when it detects a consent state change. This is the most robust approach for single-page applications where page reloads do not occur between consent changes and active tracking sessions.

Step 4: Verify

After implementing, test by opting out using the consent banner and confirming the following in the browser's developer tools:

  • Application > Session Storage no longer contains the tool's storage keys

  • Application > Local Storage no longer contains the tool's storage keys

If you are using GTM, also confirm in GTM Preview and Debug mode that the tag shows as fired after the opt-out action.