I recently needed to insert the Google Analytics script on the fly on each html page that an Apache server was sending. Kirill Minkovich has made a good overview of the standard ways for doing so. Particularly the second and third solutions are interesting because they use the ext_filter_module which is meant for such things.
External filters are slow. Since Apache 2.2.7 there is a internal SUBSTITUTE filter.
AddOutputFilterByType SUBSTITUTE text/html Substitute "s#<head(.*)>#<head$1>\ <!-- Global site tag (gtag.js) - Google Analytics -->\ <script async src=\"https://www.googletagmanager.com/gtag/js?id=UA-19913980-1\"></script>\ <script>\ window.dataLayer = window.dataLayer || [];\ function gtag(){dataLayer.push(arguments);}\ gtag('js', new Date());\ gtag('config', 'UA-XXXXXXX-X');\ </script>#iq" |
That’s it! Make sure that DEFLATE filter is not run before, otherwise the SUBSTITUTE filter will get a gzipped stream and thus will not be able to insert the code.
Note: Aaron Gloege also has a very interesting php-only solution for this problem, but I, IMHO, thought it a bit farfetched. Nonetheless, it is probably (much) faster than the one used below.
Here is a simpler version for the filter.google-analytics.php file:
<?php $ga_script = "<script type=\"text/javascript\"> var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-XXXXXXXX-X']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); </script>"; $handle = fopen ("php://stdin","r"); // Will read the whole stream. // Use $sHtmlFile = fgets($handle); for testing purposes from command line. $sHtmlFile = stream_get_contents($handle); // We allow only one replacement before one of the 3 tags. // From testing it appears that php PCRE engine replaces the // first match from the stream. So the ga_script will probably // be inserted before </head> as Google recommends. $replacements; $sHtmlFile = preg_replace( '/(<\/head>|<\/body>|<\/html>)/si', "$ga_script$1", $sHtmlFile, 1, $replacements); if ($replacements == 0) { $sHtmlFile = $sHtmlFile . $ga_script; } echo $sHtmlFile; ?> |
And of course, add the following to your apache.conf file:
LoadModule ext_filter_module modules/mod_ext_filter.so
ExtFilterDefine insert-google-analytics cmd="/bin/php /cgi-bin/filter.google-analytics.php" mode=output
AddOutputFilter insert-google-analytics htm html