Introduction
Setting up Fathom Analytics is straightforward and privacy-first by design. Unlike complex analytics platforms that require extensive configuration, Fathom focuses on simplicity: add a lightweight script, create goals as needed, and start collecting privacy-compliant data immediately.
This guide covers implementing Fathom Analytics across different environments: basic website installation, custom domain CNAME setup, SPA route tracking, multi-domain tracking, and server-side event collection.
How Fathom Differs from GA4
Fathom makes different architectural trade-offs than Google Analytics:
No cookies, no consent banners: Fathom does not set cookies or collect personal data, so it is GDPR/CCPA/PECR compliant without a consent management platform.
Smaller script: Under 2KB (vs GA4's ~45KB gtag.js). Loads with defer, so it does not block rendering or affect LCP.
One script tag: No container snippets, no SDK initialization, no config objects. Add the script, deploy, and data starts flowing.
Custom domain CNAME: Serve the tracking script from your own subdomain (e.g., stats.yourdomain.com). This makes requests first-party, which bypasses most ad blockers and increases data accuracy.
Implementation Approaches
Fathom supports multiple implementation methods depending on your needs:
1. Direct Script Embed
Works with: Static websites, simple setups
Add one script tag to your site's <head>:
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
Pros:
- Simplest implementation
- Works immediately
- No dependencies
Cons:
- Harder to manage across many pages
- May be blocked by ad blockers
2. Custom Domain (Recommended)
Works with: Any site where ad blockers reduce data accuracy
Use your own subdomain for tracking:
<script src="https://stats.yourdomain.com/script.js" data-site="ABCDEFGH" defer></script>
Pros:
- Bypasses most ad blockers
- First-party tracking
- Higher data accuracy
- Professional appearance
Cons:
- Requires DNS configuration
- One-time setup needed
3. Tag Manager Integration
Works with: Large teams, multi-tool environments
Deploy via Google Tag Manager or similar:
<!-- GTM Custom HTML Tag -->
<script>
(function() {
var script = document.createElement('script');
script.src = 'https://cdn.usefathom.com/script.js';
script.setAttribute('data-site', 'ABCDEFGH');
script.defer = true;
document.head.appendChild(script);
})();
</script>
Pros:
- Centralized management
- Version control
- Easy updates
- Testing capabilities
Cons:
- Adds complexity
- Depends on tag manager loading
- Potential delays
4. Framework Integration
Works with: SPAs, modern JavaScript frameworks
Use framework-specific libraries:
// React with fathom-client
import * as Fathom from 'fathom-client';
Fathom.load('ABCDEFGH', {
includedDomains: ['yourdomain.com'],
});
Pros:
- Native framework integration
- Automatic SPA tracking
- Type safety (TypeScript)
- Programmatic control
Cons:
- Additional dependency
- Framework-specific setup
- More complex configuration
5. Server-Side Tracking
Works with: Backend events, API tracking
Track events via Fathom's Events API:
// Node.js example
await fetch('https://cdn.usefathom.com/api/event', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
site: 'ABCDEFGH',
name: 'goal',
goal: 'PURCHASE',
value: 9999
})
});
Pros:
- Reliable tracking (no client-side blocking)
- Backend event tracking
- Cross-platform consistency
Cons:
Setup Process
Phase 1: Account & Site Setup
Step 1: Create Fathom Account
- Visit usefathom.com
- Sign up for account
- Choose plan (starts at $14/month)
- Complete onboarding
Step 2: Add Your Site
- Click "Add Site" in dashboard
- Enter your domain name
- Copy your Site ID (e.g.,
ABCDEFGH) - Save settings
Step 3: Install Tracking Script
- Copy provided script code
- Add to your website's
<head>section - Deploy changes
- Verify tracking in real-time dashboard
Phase 2: Goal Configuration
Step 1: Identify Key Events
Determine what actions matter to your business:
- Newsletter signups
- Product purchases
- Form submissions
- Trial signups
- Downloads
- Feature usage
Step 2: Create Goals in Dashboard
- Navigate to Settings > Goals
- Click "Create Goal"
- Enter descriptive name (e.g., "Newsletter Signup")
- Copy Goal ID (e.g.,
SIGNUP01) - Repeat for each goal
Step 3: Implement Goal Tracking
Add tracking code where events occur:
// Button click
<button 0)">
Sign Up
</button>
// Form submission
document.getElementById('form').addEventListener('submit', function() {
fathom.trackGoal('FORMSUBM', 0);
});
// Purchase with revenue
fathom.trackGoal('PURCHASE', 9999); // $99.99 in cents
Phase 3: Advanced Configuration
Custom Domain Setup:
- Create DNS CNAME:
stats.yourdomain.com→cdn.usefathom.com - Add domain in Fathom Settings > Custom Domain
- Wait for DNS propagation (up to 48 hours)
- Update script to use custom domain
EU Isolation (if needed):
- Enable in Settings > EU Isolation
- All European traffic processed in EU
- Schrems II compliant
Excluded Domains:
<!-- Don't track localhost or internal domains -->
<script src="https://cdn.usefathom.com/script.js"
data-site="ABCDEFGH"
data-excluded-domains="localhost,staging.yourdomain.com"
defer></script>
Phase 4: Verification & Testing
Real-Time Verification:
- Open Fathom dashboard
- Click "Current visitors"
- Visit your site in another tab
- Confirm pageview appears (within 30 seconds)
- Test goal tracking by triggering events
Network Debugging:
- Open browser DevTools
- Go to Network tab
- Filter for "fathom"
- Verify requests to
/api/eventreturn 200 OK
Cross-Browser Testing: Test on:
- Chrome
- Safari
- Firefox
- Edge
- Mobile browsers (iOS Safari, Chrome Mobile)
Implementation Patterns
Single Website
Standard Setup:
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
</head>
<body>
<!-- Your content -->
</body>
</html>
Multi-Page Website
Consistent Implementation:
Use template/layout file to include script on all pages:
<!-- header.php -->
<head>
<?php // Other head content ?>
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
</head>
Single Page Application (SPA)
Manual Pageview Tracking:
// React Router example
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
useEffect(() => {
if (window.fathom) {
window.fathom.trackPageview();
}
}, [location]);
return <Router>...</Router>;
}
Multi-Site / White Label
Separate Sites Per Domain:
- Create separate site in Fathom for each domain
- Use different Site IDs
- Track independently
OR Shared Site:
- Use one Site ID across domains
- Enable cross-domain tracking
- View aggregate data
Ecommerce Implementation
Product Pages:
<!-- Automatic pageview tracking -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
Checkout Success:
// After successful purchase
const orderTotal = 149.99;
const cents = Math.round(orderTotal * 100);
fathom.trackGoal('PURCHASE', cents);
Cart Interactions:
// Add to cart
fathom.trackGoal('ADDCART', 0);
// Checkout started
fathom.trackGoal('CHECKOUT', 0);
Environment-Specific Setup
Development
Exclude from Production Tracking:
<script src="https://cdn.usefathom.com/script.js"
data-site="ABCDEFGH"
data-excluded-domains="localhost,127.0.0.1"
defer></script>
OR Use Separate Test Site:
const FATHOM_SITE_ID = process.env.NODE_ENV === 'production'
? 'ABCDEFGH' // Production
: 'TESTSITE'; // Development
Staging
Separate Site Recommended:
- Create "Staging" site in Fathom
- Use different Site ID
- Test without polluting production data
Production
Final Checklist:
- Script uses correct production Site ID
- Custom domain configured (if using)
- Goals created and tested
- Revenue tracking verified
- Real-time dashboard shows data
- Cross-browser tested
- Mobile tested
- Performance impact validated
Best Practices
Performance
Always Use defer:
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
Avoid Blocking Execution:
// Don't wait for tracking to complete
await fathom.trackGoal('SIGNUP01', 0);
// Fire and forget
fathom.trackGoal('SIGNUP01', 0);
Privacy
Already Compliant:
- No changes needed for GDPR/CCPA
- No cookie banners required
- No consent management needed
Optional Enhancements:
<!-- Honor Do Not Track (optional) -->
<script src="https://cdn.usefathom.com/script.js"
data-site="ABCDEFGH"
data-honor-dnt="true"
defer></script>
Code Organization
Centralize Configuration:
// config/analytics.js
export const FATHOM_SITE_ID = 'ABCDEFGH';
export const GOALS = {
SIGNUP: 'SIGNUP01',
PURCHASE: 'PURCHASE',
TRIAL: 'TRIAL123'
};
export function trackGoal(goalId, value = 0) {
if (window.fathom) {
window.fathom.trackGoal(goalId, value);
}
}
Import and Use:
import { GOALS, trackGoal } from './config/analytics';
trackGoal(GOALS.SIGNUP, 0);
Error Handling
function safeTrackGoal(goalId, value = 0) {
try {
if (window.fathom && typeof window.fathom.trackGoal === 'function') {
window.fathom.trackGoal(goalId, value);
}
} catch (error) {
console.error('Fathom tracking error:', error);
}
}
Common Pitfalls to Avoid
Incorrect Site ID
<!-- Wrong - check dashboard for correct ID -->
<script src="https://cdn.usefathom.com/script.js" data-site="WRONG123" defer></script>
<!-- Correct -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
Missing defer Attribute
<!-- Blocks rendering -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH"></script>
<!-- Non-blocking -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
Revenue in Dollars Instead of Cents
// Wrong - will track $0.29 instead of $29.99
fathom.trackGoal('PURCHASE', 29.99);
// Correct - convert to cents
fathom.trackGoal('PURCHASE', 2999);
Not Tracking SPA Pageviews
// Only tracks initial page load
// No code for route changes
// Track on route change
router.afterEach(() => {
fathom.trackPageview();
});
Duplicate Script Loading
<!-- Script loaded twice -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
<!-- ... later in page ... -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
<!-- Load once in <head> -->
Next Steps
After completing basic setup:
- Install Script - Detailed installation guide
- Event Tracking - Implement goal tracking
- Cross-Domain Tracking - Track across multiple domains
- Server-Side Implementation - Backend tracking
Additional Resources: