How to Persist Visitor ID in Local Storage

Employee Emeritus

I've written a few posts on the topic of Apple's Intelligent Tracking Prevention (ITP) updates in the Safari web browser. Probably the most significant impact from these updates is ITP's restrictions around client-side cookies, specifically, that client-side cookies expire after seven (7) days.

You can use iQ Tag Management to persist a visitor ID in local storage and then send the data to your vendor. This is likely the easiest solution to workaround the Safari limitation for those using client-side tag management.

Many vendors support mapping of Visitor ID. You can use the tealium_visitor_id for mapping to override each vendor's visitor ID by configuring the mapping where needed. This solution does not attempt to write back over the current cookie value that may contain a different  tealium_visitor_id. The code examples provided below shows how to update the tealium_visitor_id to default to the value retrieved from local storage. The data layer will then contain the "most-likely-to-be-consistent" value. While this technique can be used for more than just an anonymous ID, remember that any PII information is best kept out of client-side cookies and local storage.


  • Use localStorage to store a visitor identifier value with a 1 year expiry.
  • Use the JavaScript Code extension to read and write this value.
  • Use tag data mappings to send this value to a vendor.

Get the code:

Example Code: Storing a Visitor ID in Local Storage

The code provided is a simple way to store a value in local storage, in this case the Tealium Visitor ID.

The code uses "teal_vid2" as the localStorage key as well as the attribute name in data layer object:

var localStorageKey = "teal_vid2";

Update the number 365 (number of days) in the following example to persist the value for a different length of time:

var durationInMS = 365*24*60*60*1000;
function getVisitorIdFromLocalStorage()
  var val = localStorage.getItem(localStorageKey);
return val || ""; }

The format of the value stored is {timestamp}_{value}, where the timestamp is the time the value was stored (in milliseconds), e.g.1551462917775_1551a323423465325235aafbe29177fe75.

function copyVisitorIdToLocalStorage(visitorId)
   var currentTime = new Date().getTime(),

When the value is read, the timestamp is checked for expiration. If the time since writing the value is greater than the duration, then overwrite with new ID. If it is empty, then set for the first time.

     temp = getVisitorIdFromLocalStorage();
     timeWritten = parseInt(temp.split("_")[0] || 0);
     if (temp === "" || (currentTime - timeWritten) > durationInMS)  {
        localStorage.setItem(localStorageKey, currentTime + "_" + visitorId);

In the following example, the b object is a reference to the current data layer.

b[localStorageKey] = getVisitorIdFromLocalStorage();

Keep this line to always use the localStorage value as the default:

b.tealium_visitor_id = b[localStorageKey] || b.tealium_visitor_id

Using the Code Example Provided

You can use the code example provided as-is or adapt the code for your own purposes. To use the code as-is, follow the instructions below.

Use the following steps to try it out:

  1. Open the above GitHub gist link, click Raw, and cut and paste the code your clipboard.
  2. Go to iQ Tag Management to add a new JavaScript Code extension.
  3. Paste the code into the extension.
  4. To enable, save and publish to your development (dev) environment for testing.
  5. To view the ID values in local storage, type localStorage in the web console.
  6. Map the tealium_visitor_id to a tag vendor, such as Google Analytics. For detailed information about data mapping in TiQ, see Data Mapping.
  7. Next, clear your cookies in the same browser and then view the visitor ID value sent to your tag vendor.
    Clearing out cookies effectively simulates Safari behavior when you have not visited the website in seven days.

It is unknown when or if Safari will add restrictions to local storage as it currently does with cookies set using document.cookie. Unfortunately, work-arounds such as this will probably increase the odds of this happening sooner rather than later. At the same time, it is expected that the vendors that rely entirely on first-party cookies for anonymous visitors ID's will, at some point, implement their own solution to eliminate the need for work-arounds.

Regardless, I hope you enjoy browsing this code even if it's for your own curiosity.

Happy coding!

6 Kudos