Use nonces in Google Tag Manager scripts

:person_tipping_hand: Feb 2024 update

We are experimenting with a new way to handle GTM in Discourse, which doesn’t require any of the manual configuration described below

For more info, check out Experimenting with a 'strict-dynamic' Content Security Policy (CSP)

We have made some changes recently to our Content Security Policy with regards to Google Tag Manager (see this pull request). We now use the nonce approach (as recommended by Google), which means that some updates might be necessary to your Discourse site and/or GTM tags. This guide will help you make these adjustments.


Remove the 'unsafe-inline' directive

On your Discourse instance, you can now remove the entry for 'unsafe-inline'. This directive is ignored by browsers if the policy includes a nonce- value.

Update scripts to include the nonce variable

In your GTM account, you need to ensure that the nonce value is passed to any custom scripts you may have under Custom HTML tags. (If you don’t have any Custom HTML tags, you can stop here, you’re already done.)

1. Capture the nonce value in a variable

Create a new variable in GTM with the following details:

Variable name: nonce (all lowercase)
Variable Type: DOM Element
Element ID: data-google-tag-manager
Attribute name: data-nonce

2. Include the nonce variable in scripts under custom HTML tags

If you previously had scripts like this:

<script type="text/javascript">
  // your script code here
</script>

you need to add a nonce attribute to the opening tag, like so:

<script type="text/javascript" nonce="{{nonce}}">
  // your script code here
</script>

3. Ensure “Support document.write” is enabled

Only the new rendering engine supports the nonce method, so you need to make sure this checkbox is checked:


And that’s it, now you can Save and Publish your changes and then head over to your Discourse instance and make sure there are no CSP errors in the browser console.

12 Likes

Is there a flavour for “loadScript” here? Can I pass the nonce?

Are you talking about Discourse’s loadScript function, which allows you to load a JS file? If so, you’ll need to add the file URL to the content-security-policy. Nonce values are only designed for inline scripts, and cannot be inserted at runtime.

2 Likes

what code need to pass inside the script, GTM code or what ?

Hi @pmusaraj,

I’m not seeing the option to check ‘Support document.write’ on my theme component. Am I missing something? This script also simply renders the string {{nonce}} with no replacements

That checkbox should be on the GTM admin UI. You don’t need to pass it in a theme component.

1 Like

That makes more sense. Thanks @pmusaraj

Should I be seeing a nonce-{RANDOM-VALUE} in the Content-Security-Policy header script-src? I see a sha256 value i.e. sha256-xxxxxx, looks like a hash, but no nonce.

1 Like

Yes, if GTM is enabled, there’s a nonce-RANDOM added to script-src in the security policy header.

2 Likes