Attention: The solution proposed here doesn’t work anymore
Edited April 13th, 2023:
Unfortunately (or finally), the workaround described below doesn’t work anymore. It seems that Google Tag Manager has patched the vulnerability that allowed this workaround to work.
There is still no official way to do POST requests in a Custom Tag Template per the Custom Template API documentation. So if you need to do POST requests, you’ll have to use a Custom HTML Tag instead.
===============================
Original article
Custom Tag Templates in your client side Google Tag Manager are super versatile. The sandboxed JavaScript they offer is usually enough for most usecases, even for things like outgoing HTTP requests with sendPixel
.
Unfortunately sendPixel
only supports GET requests which doesn’t cut it if your data recipient requires a POST request.
There’s also no dedicated function for POST request listed in the Templates API docs.
Doesn’t work: callInWindow('fetch', …)
The easiest way would be to simply call window.fetch
through the callInWindow
function. But it’s the Permissions setting that doesn’t allow for access to predefined window
attributes.
If you try and save the template, you’ll get an error:
Workaround: Supply a fetch reference through a GTM JavaScript Variable
To start off, create a Google Tag Manager Variable of the type JavaScript Variable (not to be confused with Custom JavaScript Variables):
That’s our reference to window.fetch
which we now just have to get into the instance of the Custom Tag Template.
On your template, create a new field of the type Text Input. I called it fetchReference
:
Inside your Tag Template’s code you can then use fetch through data.fetchReference
like you normally would:
const JSON = require('JSON');
const fetch = data.fetchReference;
const myData = { someKey: "someValue" };
fetch("//mylovelydomain.com/some-endpoint", {
method: "POST",
body: JSON.stringify(myData)
})
.then(() => {
// Call data.gtmOnSuccess when the tag is finished.
data.gtmOnSuccess();
});
Lastly, make sure the tag that’s based on your tag template references the js.fetch
variable and you’re good to go: