Skip to content

Instantly share code, notes, and snippets.

@michsch
Last active August 19, 2025 16:41
Show Gist options
  • Save michsch/a92d81187bcc37e1cc86d60e8cde2e82 to your computer and use it in GitHub Desktop.
Save michsch/a92d81187bcc37e1cc86d60e8cde2e82 to your computer and use it in GitHub Desktop.
Varify.io dynamic data layer variable
import configDataLayerVariableName from 'varify.io.config'
const fallbackDataLayerVariableName = 'dataLayer'
const globalGoogleTagManagerVariableName = 'google_tag_manager'
/**
* Get all dataLayers from Google Tag Manager configuration
* (only available if the google tag manager is already loaded)
*
* @return {Array} all dataLayer variables used in the google tag manager configuration
*/
const getDataLayersFromGtm = () => {
const gtm = window[globalGoogleTagManagerVariableName] ?? null
if (gtm == null) {
return []
}
// get all valid dataLayers if multiple google tag manager containers are used
return Object.keys(gtm).reduce((accumulator, key) => {
const item = gtm[key]
const itemDataLayer = Array.isArray(window[item.dataLayer?.name]) ? window[item.dataLayer?.name] : null
if (key.indexOf('GTM-') !== 0 || itemDataLayer == null) {
return accumulator
}
// if multiple google tag manager containers use the same dataLayer, just add it once
if (!accumulator.includes(itemDataLayer)) {
accumulator.push(itemDataLayer)
}
return accumulator
}, [])
}
/**
* Get the existing dataLayers or the default dataLayer inside an Array.
*
* @return {Array} all found dataLayer variables
*/
const getDataLayers = () => {
const dataLayerVariableName = configDataLayerVariableName ?? fallbackDataLayerVariableName
// use config dataLayer variable name or fallback if no gtm configuration is found and config is not set
if (configDataLayerVariableName != null || window[globalGoogleTagManagerVariableName] == null) {
return [window[dataLayerVariableName] = window[dataLayerVariableName] ?? []]
}
return getDataLayersFromGtm()
}
/**
* Push an event to all found dataLayers.
*
* @param {Object} eventData the dataLayer event data
* @return {Boolean} true if the event could be pushed to at least one dataLayer, ether false
*/
const pushEvent = (eventData) => {
let successful = false
const dataLayers = getDataLayers()
if (typeof eventData !== 'object' || !Array.isArray(dataLayers)) {
return successful
}
dataLayers.forEach((dataLayer) => {
if (dataLayer != null && typeof dataLayer.push === 'function') {
dataLayer.push(eventData)
successful = true
}
})
return successful
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment