cancel
Showing results for 
Search instead for 
Did you mean: 

Problem this snippet solves:

Add google analytics script in the html content of the HTTP response. Works also for other Analytics providers like Piwik.

How to use this snippet:

Installation

Files

The code below has to be imported as an ifile.

By default, you must name this ifile google.js but you can change it in the irule if required.

Google Analytics code :

<!-- Google Analytics -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', '$static::tracking_id', 'auto');
ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->

Piwik javascript code :

<!-- Piwik -->
<script type="text/javascript">
  var _paq = _paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//$static::piwik_url/";
    _paq.push(['setTrackerUrl', u+'piwik.php']);
    _paq.push(['setSiteId', {$static::siteid}]);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
<!-- End Piwik Code -->

irule

You need to install the irule on your Virtual Server.

Variables

set static::tracking_id "UA-XXXXX-Y"                            # replace the Google Tracking ID by your own
set static::siteid "UA-XXXXX-Y"                                 # replace the Piwik Site ID by your own
set static::piwik_url "https://www.mypiwik.com/piwik/piwik"     # replace the Piwik URL by your own

Features

Version 1.0

  • Insert Google Analytics JS code within html response
  • support for Piwik JS insertion
  • Manage Multiple TrackingID by hostname (see Multiple "hostname and TrackingID section")

Backlog

  • Add logging

External links

Github : https://github.com/e-XpertSolutions/f5

BONUS : Multiple hostname and TrackingID

Prerequisite

You need to add a string based Datagroup named HOST_TRACKING_MAPPING.

ltm data-group internal HOST_TRACKING_MAPPING {
    records {
        blog.e-xpertsolutions.com {
            data UA-XXXXX-Z
        }
        www.e-xpertsolutions.com {
            data UA-XXXXX-Y
        }
    }
    type string
}

The google.js ifile need to be replaced by the following example :

<!-- Google Analytics -->
<script>
    window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
    ga('create', '$tracking_id', 'auto');
    ga('send', 'pageview');
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<!-- End Google Analytics -->

Irule

when RULE_INIT {
    set static::default_trackingid "UA-XXXXX-Y"
}

when HTTP_REQUEST {
    HTTP::header remove "Accept-Encoding"
    set host [HTTP::host]
}

when HTTP_RESPONSE {
    if { [HTTP::header Content-Type] contains "text/html" } {
        if { [HTTP::header exists "Content-Length"] } {
            set content_length [HTTP::header "Content-Length"]
        } else {
            set content_length 1000000
        }
        if { $content_length > 0 } {
            HTTP::collect $content_length
        }
    }
}
when HTTP_RESPONSE_DATA { 
    set search "</head>"
    set tracking_id [class match -value -- $host equals HOST_TRACKING_MAPPING]
    if { $tracking_id eq "" } {
        set tracking_id $static::default_trackingid
    }
    HTTP::payload replace 0 $content_length [string map [list $search "[subst -nocommands -nobackslashes [ifile get google.js]]</head>"] [HTTP::payload]]
    HTTP::release
}

Code :

when RULE_INIT {
set static::tracking_id "UA-XXXXX-Y"
set static::siteid "XXXXX"
set static::piwik_url "https://www.piwik.url/piwik/piwik"
}

when HTTP_REQUEST {
HTTP::header remove "Accept-Encoding"
}

when HTTP_RESPONSE {
if { [HTTP::header Content-Type] contains "text/html" } {
if { [HTTP::header exists "Content-Length"] } {
set content_length [HTTP::header "Content-Length"]
} else {
set content_length 1000000
}
if { $content_length > 0 } {
HTTP::collect $content_length
}
}
}
when HTTP_RESPONSE_DATA { 
    set search ""
    HTTP::payload replace 0 $content_length [string map [list $search "[subst -nocommands -nobackslashes [ifile get google.js]]"] [HTTP::payload]]
    HTTP::release
}

Tested this on version:

11.5
Comments
bitisuvanje_349
Nimbostratus
Nimbostratus

We did everything as described trying to get some data to Google Analytics, single hostname, following the instructions. No traffic reaches Google Analytics. Do you guys have possible update on this topic?

 

We use BIG-IP LTM.

 

Thanks!

 

Danny_Tix
Nimbostratus
Nimbostratus

We arrived at a solution using HTML profiles - am I overlooking any major downsides to this approach?

 

HTML profile (abbreviated):

 

ltm profile html /Common/html-ga { app-service none content-detection disabled content-selection { application/xhtml+xml text/xhtml text/html } defaults-from /Common/html description none rules { /Common/GT-Private /Common/GA-Private } } ltm html-rule tag-append-html /Common/GT-Private { action { text "" } description "Google Tag Manager" match { tag-name body } } ltm html-rule tag-prepend-html /Common/GA-Private { action { text "" } description "Google Analytics" match { tag-name /head } }

Sample iRule (optional and abbreviated):

 

when HTTP_REQUEST { set disable_html 0 switch -glob [string tolower [HTTP::uri]] { /secure_app* { special case for app that leaks data in URLs pool secure_app set disable_html 1 } /legacy_app/pagenotfound/* { ... special case for app that redirects 404s ... pool legacy_app set disable_html 1 } default { ... normal logic ... pool main_app } } } when HTTP_RESPONSE { if { [HTTP::status] == 404 || [HTTP::status] == 403 || $disable_html == 1 }{ HTML::disable } }
Bryan_McCoy
Nimbostratus
Nimbostratus

I was able to get this to work for a different .js file insertion but had to make a change to the string map line at the end to remove a set of quotes and include the partition.

 

HTTP::payload replace 0 $content_length [string map [list $search [subst -nocommands -nobackslashes [ifile get "/Common/newrelic.js"]]</head>] [HTTP::payload]]

 

 

Version history
Last update:
‎07-Jun-2016 14:27
Updated by:
Contributors