Fathom Analytics Setup & Implementation | OpsBlu Docs

Fathom Analytics Setup & Implementation

How to install Fathom Analytics for privacy-first, cookie-free website tracking. Covers script deployment, custom domain CNAME setup, SPA support, and...

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

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:

  • Requires server-side code
  • No automatic pageview tracking
  • More development work

Setup Process

Phase 1: Account & Site Setup

Step 1: Create Fathom Account

  1. Visit usefathom.com
  2. Sign up for account
  3. Choose plan (starts at $14/month)
  4. Complete onboarding

Step 2: Add Your Site

  1. Click "Add Site" in dashboard
  2. Enter your domain name
  3. Copy your Site ID (e.g., ABCDEFGH)
  4. Save settings

Step 3: Install Tracking Script

  1. Copy provided script code
  2. Add to your website's <head> section
  3. Deploy changes
  4. 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

  1. Navigate to Settings > Goals
  2. Click "Create Goal"
  3. Enter descriptive name (e.g., "Newsletter Signup")
  4. Copy Goal ID (e.g., SIGNUP01)
  5. 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:

  1. Create DNS CNAME: stats.yourdomain.comcdn.usefathom.com
  2. Add domain in Fathom Settings > Custom Domain
  3. Wait for DNS propagation (up to 48 hours)
  4. Update script to use custom domain

EU Isolation (if needed):

  1. Enable in Settings > EU Isolation
  2. All European traffic processed in EU
  3. 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:

  1. Open Fathom dashboard
  2. Click "Current visitors"
  3. Visit your site in another tab
  4. Confirm pageview appears (within 30 seconds)
  5. Test goal tracking by triggering events

Network Debugging:

  1. Open browser DevTools
  2. Go to Network tab
  3. Filter for "fathom"
  4. Verify requests to /api/event return 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:

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

Graceful Degradation:

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:

  1. Install Script - Detailed installation guide
  2. Event Tracking - Implement goal tracking
  3. Cross-Domain Tracking - Track across multiple domains
  4. Server-Side Implementation - Backend tracking

Additional Resources: