(Updated 2026-07-01)
When integrating Matomo for web analytics, a common hurdle you might encounter is dealing with Cross-Origin Resource Sharing (CORS) issues.
CORS is a browser security feature designed to prevent unauthorized websites from making requests to a different domain than the one that served the page. In this guide, we will break down exactly how CORS works in relation to Matomo and show you how to configure your web server correctly to avoid blocked resources.
What is CORS?
Cross-Origin Resource Sharing (CORS) is a mechanism that allows a web page to request resources (like scripts, fonts, or API data) from a completely different domain than the one the page itself is hosted on.
By default, web browsers enforce a strict Same-Origin Policy. If your website lives on your-website.com, the browser will block any JavaScript requests attempting to fetch or read sensitive resources from analytics.com. To allow legitimate cross-origin requests, the target server must explicitly send back specific HTTP headers that approve the request.
Why and When Does Matomo Need CORS?
It is easy to mix up the direction in which CORS rules need to be applied. Depending on the feature you are using in Matomo, security is handled in one of two places:
1. Standard Tracking (Sending data to Matomo)
When the JavaScript tracking code on your website sends analytics data to your Matomo server, the Matomo server must allow your website to talk to it.
The Fix: This does not require any configuration on your own web server. You solve this directly inside the Matomo administration interface under System -> General Settings -> CORS domains, where you simply add your website's URL.
2. Heatmaps, Session Recordings, and Tag Manager Debugging
This is where your own web server comes into play. If you use Digitalist Matomo SaaS, the service is often split into two distinct domains for enhanced security:
- Tracking Domain: e.g., https://tracker.analytics.digitalist.com
- Dashboard Domain: e.g., https://dashboard.analytics.digitalist.com
When you want to view a Heatmap or a Session Recording from within the Matomo dashboard, Matomo's interface needs to fetch your website's CSS files, images, and fonts to render the page layout correctly. If your web server does not explicitly allow the Matomo dashboard to fetch these assets, the browser will block them, and your recordings will appear broken or unstyled.
Configuring CORS for Different Web Servers
Configuring CORS for Different Web Servers⚠️ Important CORS Specification Note: The Access-Control-Allow-Origin header only supports one single domain at a time (or the wildcard *, which is heavily discouraged for security reasons). You cannot separate multiple domains with spaces or commas. To allow both the tracking and dashboard domains, your server must evaluate the incoming Origin header and mirror it back dynamically if it matches an approved list.
Here is how to configure this correctly across the most common web servers:
1. Apache (via .htaccess or VirtualHost)
For Apache, we use the SetEnvIf directive to check if the incoming request comes from one of the approved Matomo domains, and then set the header dynamically based on that match.
<IfModule mod_headers.c>
# Check if the incoming Origin matches the allowed Matomo domains
SetEnvIf Origin "^https://(tracker|dashboard)\.analytics\.digitalist\.com$" AllowedOrigin=$0
# Set CORS headers dynamically based on the match
Header set Access-Control-Allow-Origin "%{AllowedOrigin}e" env=AllowedOrigin
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept"
</IfModule>
2. Nginx
In Nginx, we use a map block (which should be placed inside your http block, or just above your server block) to evaluate the domain before conditionally applying the header.
# This block goes inside the http context or above the server block
map $http_origin $allowed_origin {
default "";
"https://tracker.analytics.digitalist.com" $http_origin;
"https://dashboard.analytics.digitalist.com" $http_origin;
}
server {
listen 80;
server_name your-website.com;
location / {
# If the origin matches one of our approved domains, append the headers
if ($allowed_origin != "") {
add_header 'Access-Control-Allow-Origin' $allowed_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept' always;
}
# Rest of your application configuration...
}
}
3. IIS (Internet Information Services)
Since IIS does not allow multiple static values within the web.config file for this header, we use the URL Rewrite module to read the incoming HTTP_ORIGIN and respond dynamically if it matches our criteria.
<configuration>
<system.webServer>
<rewrite>
<outboundRules>
<rule name="Matomo-CORS-Origin">
<match serverVariable="RESPONSE_Access-Control-Allow-Origin" pattern=".*" />
<conditions>
<add input="{HTTP_ORIGIN}" pattern="^(https://tracker\.analytics\.digitalist\.com|https://dashboard\.analytics\.digitalist\.com)$" />
</conditions>
<action type="Rewrite" value="{HTTP_ORIGIN}" />
</rule>
<rule name="Matomo-CORS-Methods">
<match serverVariable="RESPONSE_Access-Control-Allow-Methods" pattern=".*" />
<conditions>
<add input="{HTTP_ORIGIN}" pattern="^(https://tracker\.analytics\.digitalist\.com|https://dashboard\.analytics\.digitalist\.com)$" />
</conditions>
<action type="Rewrite" value="GET, POST, OPTIONS" />
</rule>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Testing Your Configuration
Once you have updated your server configuration, it is vital to verify that it works properly:
- Open your website and launch your browser's Developer Tools (F12), then navigate to the Network tab.
- Launch Matomo Tag Manager in Preview mode, or trigger an action that forces Matomo to pull resources from your site.
- Click on the relevant request in the network log and look at the Response Headers section.
- Verify that Access-Control-Allow-Origin returns exactly one domain (the specific domain that initiated the call) and never both domains listed together.
Conclusion
Configuring CORS correctly is essential for advanced Matomo features like Heatmaps and Tag Manager Debugging to run flawlessly. By using dynamic validation of the Origin header on your web server, you ensure both top-tier security and an analytics environment completely free from CORS bottlenecks.