Having been away from Google Tag Manager (GTM) for a bit of a spell, a recent client project gave me a much welcome opportunity to jump back in.

Enjoying that warm fuzzy feeling of the familiar as I re-oriented myself to the UI, I was abruptly pulled out of it when one of the use cases required the need for some cryptographic hashing of Personally Identifiable Information (PII) across a variety of interactions.

See I’d become rather spoiled, with such functionality readily available in Tealium iQ which made this sort of thing an absolute doozy.

At the point of resigning myself to the work at hand I spotted something new in the GTM UI, Templates. A new feature less than a year old that elicited the same jaw dropping reaction experienced by other GTM users.

A quick read of the google documentation and my day was made, they have an api providing access to the SHA-256 hashing algorithm.

gtm template sha-256 api

I expected that someone had already written a perfectly suitable hashing template, so into the gallery i went only to find that the single hashing template available was a re-work of the google analytics tag with the ability to hash dimensions. A good effort but not quite what I was after as the data potentially would need to be passed to a variety of tag tech.

So, filing in the gap, I’ve prepared a cryptographic hashing template available for you to use in the google tag manager community gallery aptly called, ‘CryptoMe’.


Now I’m not going to go into the ins and outs of the GTM templates feature, this subject being more than adequately covered by GTM’s unofficial documentation writer and all-round legend Simo Ahava to whom I also owe a nod of gratitude in edging me to the final solution.

Putting it together

There are two template types, Variable templates, and Tag templates. My first instinct was to create a variable template that would simply return the encrypted value. Much to my frustration no matter what I tried I simply could not get it to work, returning instead an undefined value.

In conversation with Simo, he pointed out what should have been obvious. The SHA-256 api call was an async operation while the variable code runs synchronously, so it simply skips over to the return statement while the call resolves.

Ok, onto the tag template.

The tag’s objective is it to output a custom dataLayer event with the hashed value passed in the object together with any other data points you may need. This gives you the flexibility of passing the data to whatever tag tech you want.

To build it we first define the Fields we need for the template. The first two are the main input fields of type text. One takes the name you want for the custom event, the other the value you want encrypted.

The other two fields are for the additional data points, a checkbox to switch on the option and a field of type ‘simple table’ which allows end users to create a table of key-value pairs which we will then pass into the event object.

The tag code

To do this we required 4 api functions (not counting the logToConsole used for debugging purposes during the build).

createQueue which allows us to create an array in window and returns a push function to push the values into that array, essentially, we can create the equivalent of dataLayer.push within the sandboxed js.

To get this to work we will also require the queryPermission to check that the necessary permissions on access_globals are available.

The makeTablemap to turn our key value table into an object of key value pairs.

And finally, the sha256.

const log = require('logToConsole');
const check = require('queryPermission');
const create = require('createQueue');
const hash = require('sha256');
const map = require('makeTableMap');

You then want to create:

  • dataLayer push call
  • a merge function to merge all the various key value pairs into the one object
  • the success and failure call backs
  • and finally the call for the encryption and push to dataLayer
// The dataLayer push
const push = create('dataLayer');

// a function to merge all the object key value pairs
const merge = function(){
const obj = {},
l = arguments.length;
let i = 0,
for (; i < l; i++){
for (key in arguments[i]) {
obj[key] = arguments[i][key];
return obj;

const event = {'event': data.event};
const other = map(data.add_fields, 'key', 'value');


const onSuccess = () =>{

const onFailure = () => {

//Now let's hash

hash(data.to_hash, (digest) => {
const h = {'hash': digest};
const dlayer = merge(event, h, other);
if (check('access_globals', 'readwrite', 'dataLayer')) {
}},() =>{onFailure();},{outputEncoding: 'hex'});

The last step is to setup the permissions for the access global variables.

Simply add the key you declared using the createQueue function, in this case ‘dataLayer’, and set read write permissions to ‘true’.

Using the Tag

In the template gallery search for CryptoMe and add it. Then create a new tag and select the CryptoMe template tag which should appear under custom.

Then simply fill in the tag fields. Give your event a name, choose the value to encrypt and pass any additional value pairs you need.

The result, a custom event with all the data points you need and PII encrypted ready to pass to whatever tag tech you need.

I hope you find this useful, please leave any comments, feedback, or improvements you would like in the comments below, and of course feel free to take this adapt it for your own means.

Tableau Expert | Alteryx ACE Emeritus | Digital AnalyticsGavin Attard is a Consultant at 120feet. An analytics expert that applies over 15 years of commercial and marketing experience across multiple verticals with geek level technical skills in the field of data analytics, digital analytics implementation, target marketing, customer insight and enabling data orchestration for campaign management and personalisation.

Alteryx ACE Emeritus and a Tealium Expert, Gavin helps businesses maximise their opportunities by enabling their ability to design experiences that drive engagement.