note

You've probably already seen it:

var datalayer = [];

datalayer.push({
	event: 'test'
});

// later we load the gtm script and it processes the infos
// and when we call push again it processes it immediately.
datalayer.push({
	event: 'second'
});

datalayer is an Array. The trick is just to redefine the push method.

function pushModule(root, name, callback) {
	// new push method
	function push(data) {
		root[name]._push.apply(root[name], arguments);
		callback(data);
	}

	// if not defined before
	root[name] = root[name] || [];

	// save native push method
	root[name]._push = root[name].push;
	root[name].push = push;

	console.log(root[name].push);

	for (var i = 0; i < root[name].length; i++) {
		callback(root[name][i]);
	}
}

// usage
pushModule(window, 'datalayer', handlerFunction);

In this code excerpt, we first define our new push function then we save the native one to replace it with our version.

Then we process all the existing entries in the table.

This pattern has the great advantage of enabling the provisionning of events, behavior or data on a page without having the consumer ready at the moment of publication.

The script consuming the array can then be loaded async/defer or just at the bottom of the page.

We use this in our development to 1) build list of components that needs js behaviors "upgrades" and 2) to expose "events" for the analytics, and this while still being able to defer the load of the scripts in charge.

About me

Stuff I do with my brain, my fingers and an editor:

(Front-end) development - typescript, Vue, React, svelte(kit) web architectures web performance API design pragmatic SEO security Accessibility (A11y) front-end dev recruitment and probably more...

Feel free to , check out my open source projects, or just read the things I write on this site.