Modern adblockers increasingly block tracking based on hostname patterns (e.g. analytics.*, stats.*) and file paths such as matomo.php.
Even if you customise the request path, some filters still match the hostname.
To avoid this, you can make Matomo Tag Manager load entirely through the first-party domain of each tracked site.
The browser will only communicate with the site’s own domain. All communication with the actual Matomo server takes place server-side via reverse proxy.
This preserves legitimate analytics, respects consent management, and avoids accidental blocking by over-aggressive filter lists.
Tested and works with: Adguard on, Brave browser ![]()
Goal
Convert third-party tracking:
https://matomo-server.tld/js/container_ABC.js
https://matomo-server.tld/matomo.php
Into completely first-party URLs like:
example.com = domain to track
https://example.com/app-container.js
https://example.com/app-collect
(You can name them anything — avoid words like “analytics”, “matomo”, “stats”, “track”, “collect.php”, “pixel.php” etc.)
Behind the scenes:
example.com → Nginx reverse proxy → Matomo server
1. Add Reverse Proxy Rules (on EACH tracked site)
In your site’s Nginx config
(or Plesk → Domain → Apache & Nginx settings → Additional Nginx directives):
Replace:
MATOMO_SERVERwith your actual Matomo host
CONTAINER_FILE.jswith your container script
/app-container.jsand/app-collectwith any names you prefer
# First-party Matomo tracking endpoint
location = /app-collect {
proxy_pass https://MATOMO_SERVER/path/to/matomo.php;
proxy_set_header Host MATOMO_SERVER;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_redirect off;
}
# First-party Tag Manager container script
location = /app-container.js {
proxy_pass https://MATOMO_SERVER/path/to/js/CONTAINER_FILE.js;
proxy_set_header Host MATOMO_SERVER;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_redirect off;
}
Tip:
Use neutral path names such as:
/app.js
/app-config.js
/core.js
/app-endpoint
/api-event
/api-hit
Avoid sensitive words like:
analytics
matomo
stats
pixels
tracking
collect.php
events.php
monitor
2. Configure Matomo Tag Manager
Inside Matomo:
Tag Manager → Container → Variables → Matomo Configuration
Set these:
✓ Matomo URL
Your first-party domain (the site being tracked):
https://example.com
✓ Custom Tracking Request Target Path
The path you created in Nginx:
app-collect
(No leading slash.)
Matomo will now send hits to:
https://example.com/app-collect?...
Nginx will forward these internally to your actual Matomo server.
Publish the container afterwards.
3. Update Your Tag Manager Snippet
Replace the default script source:
<script src="https://MATOMO_SERVER/path/to/js/CONTAINER_FILE.js"></script>
with your first-party proxied version:
<script src="https://example.com/app-container.js"></script>
This ensures the browser never loads anything from your Matomo server directly.
Done!
You now have:
Fully first-party Matomo Tag Manager
Container script served from the site’s own domain
Tracking endpoint served from the site’s own domain
Adblockers see NO references to matomo.php, analytics hosts, or tracking keywords
Requests are internal-only between your site and Matomo
Works with aggressive blocker lists
No modification to Matomo core
Safe for updates and easy to replicate across multiple sites
Notes
-
Repeat the proxy block for each site you want to track.
-
Each site still uses the same central Matomo installation.
-
Choose endpoint names that do not contain typical tracking words.
-
Keep caching of the container JS modest (1 hour recommended) to keep tags fresh.
-
This does not bypass user consent - you should still honour Do-Not-Track and your CMP