Un tag manager es -en el contexto de una implementación web- un inyector de Javascript. Como tal, tiene acceso a muchas de las apis, métodos y objetos que expone tu navegador. Uno de estos casos son los Javascript closures. Este concepto hace referencia a una cualidad intrínseca de este lenguaje que se da cuando una función se ejecuta dentro de otra función ya ejecutada. Esto te va a permitir ejecutar tareas complejas a través de una única función a la que puedes llamar en cualquier momento, un game winner si lo sabes aprovechar en tus implementaciones. En este post te voy a hablar de cómo puedes aprovechar los Javascript closures desde Google Tag Manager (GTM).
Los closures son una cualidad del Javascript a través de la cual se puede acceder al contexto de ejecución de una función que ha terminado de ejecutarse. En la práctica esto se lleva a cabo desarrollando una función que devuelve otra función. Suena un poco etéreo, lo sé, pero si lo sabes aprovechar bien, se puede convertir en una herramienta muy potente que puedes aprovechar en tus implementaciones de analítica (o cualquier otra desarrollo).
Con los closures de Javascript puedes desarrollar funciones a las que llamar en cualquier momento con una sintaxis súper sencilla para que se encarguen de realizar operaciones complejas. Google Tag Manager (GTM) se presta muy bien a aprovechar los closures a través de su Custom Javascript Variable. Esta variable es, por definición, una función anónima que debe devolver un valor. Lo único que tienes que hacer es adaptarla para que sea una función que devuelva otra función.
El gran Simo Ahava ya escribió sobre esto hace algún tiempo en su blog: ‘#GTMTips: Create utility variable returning functions’. Él propone aprovechar los Javascript closures para generar -a través de un Custom Javascript Variable- un utility function (algo así como una función herramienta) para crear cookies sin necesidad de reescribir el mismo código complejo una y otra vez. He seguido su recomendación en numerosas ocasiones, y la verdad es que me ha resultado muy útil. Yo le cojo el testigo para explicarte qué son las clausuras en Javascript y cómo puedes aprovecharlos desde Google Tag Manager en un caso muy particular pero muy común también: exponer en el dataLayer arrays de valores que de otra forma estarían muy anidados dentro de la propia capa de datos de GTM.
Los closures en Javascript: el scope de una función y su execution context
Para entender qué son los closures en Javascript hay que entender también qué son los scopes. En Javascript, cuando una función se ejecuta, tiene acceso a su propio scope (las variables contenidos dentro de la misma función, por ejemplo) así como a todos los scopes superiores. Esto quiere decir que una función siempre podrá acceder a variables y métodos del objeto DOM, Window…y de cualquier otra función dentro de la cual se encuentre.
Fíjate en el siguiente ejemplo:
Como ves, es una sencilla función que accede a una variable del DOM, que es el objeto dentro del que está contenida. Es decir, la función ha accedido a un scope superior al suyo.
Pero además, en Javascript una función que se ejecuta dentro de una función puede acceder al execution context (y por lo tanto a cualquier variable) de la primera cuando ésta ya ha terminado de ejecutarse (el contexto de ejecución de una función se crear al ejecutarse ésta y se destruye al terminar de ejecutarse) ¿Cómo es posible esto? Por una parte por lo que te acabo de explicar: la función está contenida dentro de la función que ya ha terminado de ejecutarse, y por lo tanto tiene acceso a su scope. Y por otra porque el motor de Javascript que ejecuta el código (tu navegador, por ejemplo) guarda una referencia a las variables que se hayan podido establecer en el contexto de ejecución de una función que contiene -y devuelve- otra función. Esta es la esencia de la clausura: la función se aferra a su contexto de ejecución, y el de la función superior que la contiene.
Te pongo un ejemplo. Fíjate en el siguiente código, verás que es una función que devuelve otra función:
function howOldWereYouIn(yearOfBirth) {
return function(year){
return year - yearOfBirth;
}
}
Eso tiene otro aspecto, ¿verdad? La función howOldWereYouIn se ejecuta, y cuando termina de ejecutarse, la función anómina que está contenida dentro se ejecuta también. ¿Y te das cuenta de lo que pasa? Esta segunda función anónima se ejecuta con su argumento, pero también tiene en cuenta el argumento de la primera, que en realidad ya ha terminado de ejecutarse, y por lo tanto su contexto de ejecución (incluyendo este argumento) ya no existe. ¡Esa es la clausura!
Fíjate ahora en esta otra sintaxis:
Al alojar la función howOldWereYouIn –y su argumento- en una variable, acabo de crear uno de los utility functions de los que Simo habla en el post al que enlazo un poco más arriba. Ahora no tengo más que llamar a esta variable junto con un argumento para ejecutar el cálculo desarrollado: cuántos años tenía en un determinado año. Y puedo hacerlo tantas veces como quiera sin tener que reescribir el código. La clausura se encarga de todo.
Los Javascript closures en Google Tag Manager (GTM)
Los Custom Javascript Variables de Google Tag Manager te permiten explotar de una forma muy sencilla todo el potencial de los closures. Por definición, una variable de este tipo debe contener una función anónima que devuelva un valor. Lo único que tienes que hacer es configurar la variable para que contenga una función anónima que devuelva otra función.
Te voy a mostrar cómo hacerlo con un caso de uso con el que me he topado un montón de veces a lo largo de los años: generando un dataLayer de Enhanced Ecommerce plano y agnóstico en Google Tag Manager para que pueda ser aprovechado por cualquier vendor (el dataLayer de GTM tiene unas especificaciones muy rígidas en los que a Enhanced Ecommerce se refiere) Así, en lugar de tener 4 product id’s en diferentes anidamientos del dataLayer, los tendrás todos contenidos en un sencillo array (esta es, de hecho, la estructura del data layer de Enhanced Ecommrce de Tealium iQ). Para ello necesitas desarrollar un sencillo script en un Custom Javascript Variable que acceda a los valores del dataLayer necesarios, los procese y los devuelva a la capa de datos alojados en un array.
Fíjate, este es el código que he desarrollado yo. Es una función anónima que devuelve otra función que a su vez está esperando un parámetro. Es decir: es un Javascript closure.
//Code for 'CJS - Flat EEC data layer generator' Custom Javascript Variable
function(){
try{
return function(items){
//Create a local reference to the global GTM dataLayer
var dataLayer = window.dataLayer || [];
//Create an empty array for each of the keys to be pushed to the dataLayer
var item_names_array = [];
var item_positions_array = [];
var item_categories_array = [];
var item_prices_array = [];
//Run a basic for loop through the indicated properties of the items argument and push their values to the previosuly set arrays
for (i = 0; i < items.length; i++){
item_names_array.push(items[i]['item_name']);
item_positions_array.push(items[i]['index'].toString());
item_categories_array.push(items[i]['item_category']);
item_prices_array.push(items[i]['price'].toString());
};
//Execute dataLayer.push() with four new keys, each one populated with the previously created -and now populated- arrays
dataLayer.push({
'product_impression_name':item_names_array,
'product_impression_position':item_positions_array,
'product_impression_category':item_categories_array,
'product_impression_price':item_prices_array
});
}
}
catch(error){}
}
Como ves, el código recibe el argumento items del dataLayer, lo procesa, y crea cuatro arrays que empuja al dataLayer. ¿Cómo ejecutar ese código? A través de un Custom HTML Tag que sigue la misma sintaxis que los ejemplos que te he explicado al principio de este post:
La secuencia de acontecimientos es la siguiente. Un usuario visualiza una página en la que hay un dataLayer de tipo Enhanced Ecommerce implementado, como por ejemplo analyticsimplementations.com:
El tag (de tipo HTML Personalizado) ‘CHTML – JS Closure – items_array’ se ejecuta y llama a la función contenida en el Custom Javascript Variable pasándole como argumento otra variable (en este caso de tipo dataLayer): ‘DLV – ecommerce.items’.
El Javascript closure accede a este contexto de ejecución y a la variable ‘DLV – ecommerce.items’. El resultado: cuatro nuevas claves en el dataLayer de Google Tag Manager exponiendo información de Enhanced Ecommerce de forma plana en un array.
Reflexiones finales
Muchos vendors que se implementan desde Google Tag Manager necesitan que el dataLayer exponga ciertos valores ajustados a un formato específico. Es el caso, por ejemplo, de Meta (hasta hace poco Facebook). Su Conversions API (API de Conversiones) está esperando que el parámetro content_ids sea un array que contenga los id’s de los contenidos que se están trazando.
Pues bien, el caso de uso que te he explicado en este post daría respuesta a este requerimiento de Facebook, pero no es más que un ejemplo. Mi objetivo al escribir este post ha sido el de explicarte qué son los Javascript closures, cómo puedes aprovecharlos desde Google Tag Manager (GTM) y el enorme potencial que tienen las Custom Javascript Variables para explotar estas clausuras a través de funciones reutilizables y fáciles de llamar. ¡Espero te sirva de ayuda en tus implementaciones!
2 comentarios en «Cómo aprovechar los Javascript closures en Google Tag Manager (GTM)»
Los comentarios están cerrados.