Why am I seeing duplicate pathnames in my data?
It usually means the same page is being served with more than one variation of the URL. How those variations show up depends on whether you’ve turned on Multi-domains:
- Multi-domains off (the default): the Pages box groups by pathname only, so
http/https,www/non-wwwand other domains serving the same path are combined into one row. Duplicates here come from differences in the path itself, like a trailing slash, different letter case, or certain query parameters. - Multi-domains on: pages are grouped by domain and pathname. The row label hides the protocol and
www., so if your site can be visited at bothhttp://example.com/pageandhttps://www.example.com/page, you’ll see separate rows for what looks like the same pathname.
Below are the most common causes, how to confirm what’s happening, and fixes we recommend.
How to view the full URL in your dashboard
If you’re unsure which URL Fathom recorded, hover over the pathname in the Pages box. Your browser will show the link (typically in the bottom-left corner). With Multi-domains on, the link includes the recorded domain, which is the quickest way to spot www vs non-www or a different domain/subdomain. The link always uses https, so it won’t reveal an http vs https difference, and with Multi-domains off it uses your site’s domain rather than the recorded one.
Common causes and how to fix them
1) Both www and non-www versions are accessible
Symptom: You can visit both https://example.com/page and https://www.example.com/page and they both load without redirecting. With Multi-domains on, Fathom will show these as separate rows.
Fix: Choose a primary host (with or without www) and permanently redirect the other to it.
Example fixes:
- DNS + web server: Point both hosts at your server, but have the secondary host 301 redirect to the primary.
- NGINX (force non-www):
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name www.example.com;
return 301 https://example.com$request_uri;
# ssl_certificate / ssl_certificate_key ...
}
- Apache (.htaccess, force www to non-www):
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]
- Cloudflare: Use a single A/AAAA record for the primary host. Add a Redirect Rule to send
www.example.com/*→https://example.com/$1(301).
Tip: Be consistent with internal links and your <link rel="canonical"> tag so everything points to your chosen host.
2) Both http and https are accessible
Symptom: http://example.com/page and https://example.com/page both load. With Multi-domains on, each protocol shows up as a separate row.
Fix: Redirect all HTTP traffic to HTTPS, and consider enabling HSTS.
Example fixes:
- NGINX (force HTTPS):
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
- Apache (.htaccess):
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
- Cloudflare: Turn on “Always Use HTTPS” and (optionally) HSTS after testing.
3) The domain differs (localhost, staging domains, or subdomains)
Symptom: With Multi-domains on, you see the same pathname under different domains. With it off, visits from these domains are counted in the same pathname row. For example:
https://example.com/pricing(production)https://staging.example.com/pricing(staging)http://localhost:3000/pricing(local dev)
Fix options:
- Block non-production domains using Allowed Domains so dev/staging traffic is never recorded.
- If you do want subdomain data, enable Multi-domains so each domain/subdomain is clearly grouped and reported.
Recommendation: For most teams, allow only the production domain(s) and exclude localhost/staging entirely. Enable multi-domains only when you intentionally want to analyse multiple domains or subdomains under the same site.
Canonical link doesn’t match the page URL
Fathom will default to using the page’s canonical URL if a <link rel="canonical" href="..."> tag is present. If your canonical points to a different host or path than the one the visitor is on, you’ll see data attributed to that canonical URL instead.
How to check:
- Open the page in your browser and view source (or inspect).
- Find the
<link rel="canonical">tag and confirm thehrefexactly matches your intended, public URL (correct protocol,wwwvs non-www, correct domain/subdomain, correct path and trailing slash conventions). - Hover over the pathname in Fathom’s Pages box to compare the recorded URL with your canonical.
Fix: Update your canonical tags to match the real, public URL you want to report on. This will also help your site’s SEO.
Alternative: If you have a unique setup and do not want Fathom to use canonical URLs, you can tell the Fathom script to ignore them. Instructions here.
Verification checklist
- Open each variant (http vs https, www vs non-www, subdomain vs root) and make sure every non-primary URL 301-redirects to your primary URL.
- Check a few representative pages for a correct canonical tag that matches your chosen host and path.
- In Fathom (with Multi-domains on), hover page rows to confirm the domain matches your expectations.
- If you use test/staging/local environments, configure Allowed Domains (to block them) or Multi-domains (to measure them intentionally).
FAQ
Will this merge my historical duplicates? No. Redirects and canonical fixes prevent future duplication. Historical rows will remain as they were recorded.
Do trailing slashes matter?
Yes, https://example.com/page and https://example.com/page/ are distinct URLs. Pick a convention, redirect the other, and make sure your canonical tags and internal links follow the same convention. Letter case matters too, so /Page and /page are recorded separately.
Do query strings matter?
Mostly no. By default, Fathom strips query strings from page URLs, so https://example.com/page?a=1 and https://example.com/page are reported as the same page. UTMs (utm_source, utm_medium, utm_campaign, utm_term, utm_content) and the ref, keyword, q and s parameters are read for attribution, and they don’t create separate page rows. The exceptions are action, name, pagename, tab and via, which we keep on the pathname, so https://example.com/page?tab=pricing shows up as its own row.
Still having issues?
If you’ve worked through the above and still see unexpected duplicates, contact our support team and send us a couple of example URLs (the exact URLs you see when you hover in the Pages box) and we’ll help you untangle what’s going on.