Skip to content

Send APP+WEB Hits to any remote endpoint

David Vallejo

Google released APP+WEB Properties some weeks ago now, and one of the most missed features looking back to Universal Analytics, is the chance to work with a customTask ( Hi Simo!!! ).

In this post I’ll cover how to send a copy of the hits to anywhere we want, in case we want to hold a copy of them, or processing them in some other place (like snowplow)

First, we need to take in mind that APP+WEB hits, may contain +1 hits into their payload, therefore we’ll splitting the hits in single hits before sending them to our endpoint. If you want to learn more about how APP+WEB Protocol works you can take a look to this post

APP+WEB API makes use of navigator.sendBeacon to send the hits, so we’ll writting a proxy pattern to listing to sendBeacon calls in order to be able to grab the payloads and sending them back to our own endpoint. In the middle of this process we’ll be splitting the hits in single hits.

On this specific example we’re sending the data via POST, but it can be easily be send as a QS payload. Just feel free to modify the code at your needs ).

In order to have this working, we’ll need create a new TAG in Google Tag Manager ( or just add this code into your site in some other way ) with the following code. ( feel free to modify the endpoint variable at the end. Let’s call it: “TOOL – APP + WEB Remote Logger”

"use strict";
(function() {
    try {
        var proxied = window.navigator.sendBeacon;
        window.navigator.sendBeacon = function() {
            var parse = function getQueryParameters(str) {
                return (str ||^\?)/, "").split("&").map(function(n) {
                    return (n = n.split("=")),
                    (this[n[0]] = n[1]),
            // Check if it's a APP+WEB hit
            if (arguments && arguments[0].match(/google-analytics\.com.*v\=2\&/)) {

                var payloads = [];
                var qs = arguments[0].split("?")[1];
                // APP+WEB Can hold more than 1 hit on the same payload, we'll send separete this, let's split them
                if (arguments[1] && !qs.en) {
                    arguments[1].split("\n").forEach(function(e) {
                        var tmp = Object.assign(parse(qs), parse(e));
                } else {
                var data = {
                    records: payloads
                var endpoint = "https://myownendpoint/g/collect";
                fetch(endpoint, {
                    method: "POST",
                    body: JSON.stringify(data)

            return proxied.apply(this, arguments);
    } catch (e) {}

After we have that tag in place we’ll need to use the tag secuencien with our pageview tag ( this needs to run just one, so don’t add it to other hits ).

And now we’ll only need to publish our container, and a copy of the hits will be sent to the endpoint we’ve defined on the code! Easy!