Yes, Matomo can be used with CSP. However, you cannot use the standard tracking code generated by the Tracking Code Generator in the Matomo UI as it is not allowed to use inline scripts when having CSP enabled. CSP is a security concept to prevent cross-site scripting (XSS) attacks as well as related attacks.

Setting up the JavaScript Tracker

Instead make sure to put the tracking code into files like this:
<script src="https://example.com/tracking.js"></script>
<script src="https://matomo.example.com/matomo.js" async defer></script>

The file matomo.js should be loaded from your Matomo server and tracking.js should contain the actual tracking calls like this:

var idSite = 1;
var matomoTrackingApiUrl = 'https://matomo.example.com/matomo.php';

var _paq = window._paq = window._paq || [];  
_paq.push(['setTrackerUrl', matomoTrackingApiUrl]);
_paq.push(['setSiteId', idSite]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);  

Make sure to specify the correct idSite if needed and to replace the Matomo Tracking API URL. You can build this URL by appending /matomo.php to your Matomo domain.

The tracking.js file will be unique for each website that you will be installing the Matomo JavaScript tracking code on and will need to be stored in your webserver root folder.

Setting up Matomo Tag Manager

If you’re using Matomo Tag Manager instead of the standard JavaScript tracking code, you can to set the tracking code up to work with CSP as follows:

<script src="https://example.com/tracking.js"></script>
<script src="https://matomo.example.com/js/container_XXXXX.js" async defer></script>

The file js/container_XXXXX.js should be loaded from your Matomo server, replacing the container ID with the one generated by Matomo and tracking.js should contain the following:


    var _mtm = window._mtm = window._mtm || [];
    _mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'}); 
 

Important note: The example above assumes that you are using the Matomo Tag Manager as the Default Tracker and that the Matomo Javascript tracker is bundled with the Matomo Tag Manager container. If you are using both the JavaScript tracker and Matomo Tag Manager, you will need to combine both of the above methods.

Configuring Content-Security-Policy

If you load matomo.js from a different domain make sure to allow the Matomo domain like this: script-src 'self' http://matomo.example.com. If you load third party JavaScript files or if you have a CDN you might have to add even more domains to the whitelist.

An example response header looks like this:

Header set Content-Security-Policy "default-src 'self'; connect-src https://matomo.example.com; script-src 'self' https://matomo.example.com; img-src 'self' https://matomo.example.com; style-src 'self'; frame-ancestors 'self'; frame-src 'self';"

If CSP should work in all browsers you might have to add further headers. At the time of writing this article you might as well need to set X-WebKit-CSP for Safari and X-Content-Security-Policy for Internet Explorer support. Read more about Content Security Policy.

Using a nonce to enable inline JavaScript

You can use inline JavaScript if you setup a nonce in your CSP configuration and set the same nonce as the value of the nonce attribute when including the inline Matomo JavaScript like this:
<!-- Matomo -->
<script nonce="the_nonce_from_your_csp_config">
... Matomo Tracking Code...
</script>
<!-- End Matomo Code -->

This approach also works with Matomo Tag Manager and, for Matomo version 4.12 forward, it means that any JavaScript included as part of a Custom Html tag will automatically inherit the nonce and will not be blocked by CSP. More in depth information about using a nonce with CSP can be found in the MDN web docs.

Previous FAQ: JavaScript Tracking Client API reference