We recently came across an analytics implementation issue that we haven’t seen before — a rather delightful and novel experience for us these days! While this issue’s existence has been documented across the web (as we discovered when searching for it specifically), it was new to us, and we wanted to make this issue known to our blog readers in case it rears its ugly head.
The long and short of it is that a Content Security Policy can break your Google Tag Manager implementation, but with the right fix, the two can coexist peacefully.
What is a Content Security Policy (CSP)?
A Content Security Policy (CSP) is an extra layer of security that helps protect a website from some types of injection-based and Cross Site Scripting (XSS) attacks. A CSP prevents the browser from executing any scripts from third-party domains unless those domains are on an administrator-control whitelist.
Why does it not work with Google Tag Manager?
Since Google Tag Manager is a third-party vendor attempting to load a third-party script, websites that employ a CSP will refuse to execute it, assuming that the script is a possible attack on the website.
How can you tell that your Google Tag Manager script is being disabled by a CSP?
A CSP blocking the GTM script means that GTM, even when otherwise implemented correctly, will not fire any tags or collect any data. If you’re tearing your hair out trying to figure out where your implementation went wrong, a CSP may be the culprit.
Here are a few ways that you can identify whether a CSP is the culprit behind your GTM woes:
- Check to see if Google Tag Manager Preview Mode is working on the website where you have Google Tag Manager properly deployed.
- Check the Developer’s Console after loading a page on your website, and look for a message akin to:
“Refused to execute inline script because it violates the following Content Security Policy directive: “script-src ‘self’ ‘unsafe-eval’ *.googletagmanager.com”. Either the ‘unsafe-inline’ keyword, a hash (‘example’), or a nonce (‘nonce-…’)” is required to enable inline execution.”
- Check to see whether there is a meta tag in the source code on a page on your website that looks something like this:
<meta http-equiv=”Content-Security-Policy” content=”default-src ‘self’; img-src https://*; child-src ‘none’;”>
How to enable the Google Tag Manager snippet on a CSP website
Hey cool, Google Developers knows this is a thing and provides documentation for resolving the issue. The rub is that it does take a little know-how and dev work to resolve it.
The recommended solution is to use a server-generated nonce (which stands for “number used once”) and to supply that nonce value in the Content Security Policy script-src directive.
Here’s what that looks like:
Content-Security-Policy: script-src ‘nonce-{SERVER-GENERATED-NONCE}’; img-src www.googletagmanager.com
Then you use the nonce-aware version of the inline Google Tag Manager snippet, setting the nonce attribute on the inline script element to this same value, which should look like this:
<!– Google Tag Manager –>
<script nonce='{SERVER-GENERATED-NONCE}’>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({‘gtm.start’: new Date().getTime(),event:’gtm.js’});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!=’dataLayer’?’&l=’+l:”;j.async=true;j.src= ‘https://www.googletagmanager.com/gtm.js?id=’+i+dl;var n=d.querySelector(‘[nonce]’); n&&j.setAttribute(‘nonce’,n.nonce||n.getAttribute(‘nonce’));f.parentNode.insertBefore(j,f); })(window,document,’script’,’dataLayer’,’GTM-{YOUR-CONTAINER-ID}’);</script>
<!– End Google Tag Manager –>
While we only highlight one way to resolve this issue, it’s great to have this instance in your analytics troubleshooting toolkit. A key consideration as you delve into this issue is to ensure you aren’t fiddling with a site’s CSP without looping in the person who set it up; it may be that they have their own way they’d like to whitelist sites, and you may be able to work with them on configuration. Particularly as web security continues to be a high priority, we’re likely to see this come up more and more frequently as time goes on.