Fathom Analytics Troubleshooting & Debugging | Blue Frog Docs

Fathom Analytics Troubleshooting & Debugging

Common issues, debugging techniques, and solutions for Fathom Analytics

Fathom Analytics Troubleshooting & Debugging

Common Issues

Script Not Loading

Symptoms:

  • No pageviews appearing in dashboard
  • fathom is not defined errors in console
  • Network requests to Fathom not appearing

Possible Causes & Solutions:

1. Script URL Incorrect

<!-- ❌ Wrong -->
<script src="https://fathom.com/script.js" defer></script>

<!-- ✅ Correct -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>

2. Missing Site ID

<!-- ❌ Wrong -->
<script src="https://cdn.usefathom.com/script.js" defer></script>

<!-- ✅ Correct -->
<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>

3. Ad Blocker Interference

  • Use custom domain tracking: https://stats.yourdomain.com/script.js
  • Set up custom domain in Fathom settings
  • Test in incognito mode or with ad blocker disabled

4. Content Security Policy (CSP) Blocking

<!-- Add to CSP header -->
Content-Security-Policy: script-src 'self' cdn.usefathom.com;

5. Script Placed Incorrectly

<!-- ✅ Place in <head>, not at end of <body> -->
<head>
  <script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>
</head>

Goals Not Tracking

Symptoms:

  • Events firing in console but not appearing in dashboard
  • Goal shows 0 conversions
  • Network requests successful but no data

Possible Causes & Solutions:

1. Incorrect Goal ID

// ❌ Wrong - check your Goal ID in Fathom dashboard
fathom.trackGoal('ABCD1234', 0);

// ✅ Correct - use exact ID from dashboard
fathom.trackGoal('SIGNUP01', 0);

2. Goal Not Created in Dashboard

  • Navigate to Settings > Goals
  • Verify goal exists and is active
  • Create goal if missing

3. Script Not Loaded Before Goal Tracking

// ❌ Wrong - script might not be loaded yet
fathom.trackGoal('SIGNUP01', 0);

// ✅ Correct - check if loaded
if (window.fathom) {
  fathom.trackGoal('SIGNUP01', 0);
}

// ✅ Or wait for load
window.addEventListener('load', function() {
  if (window.fathom) {
    fathom.trackGoal('SIGNUP01', 0);
  }
});

4. Revenue Value Format Error

// ❌ Wrong - decimals not supported
fathom.trackGoal('PURCHASE', 29.99);

// ❌ Wrong - string not supported
fathom.trackGoal('PURCHASE', '2999');

// ✅ Correct - integer in cents
fathom.trackGoal('PURCHASE', 2999);

5. Tracking Duplicate Events

// ❌ Wrong - form submits before tracking completes
form.addEventListener('submit', function() {
  fathom.trackGoal('FORMSUBM', 0);
  // Form submits immediately, request might be cancelled
});

// ✅ Correct - add small delay or use beacon
form.addEventListener('submit', function(e) {
  e.preventDefault();
  fathom.trackGoal('FORMSUBM', 0);

  setTimeout(function() {
    form.submit();
  }, 100);
});

Pageviews Not Showing Up

Symptoms:

  • Dashboard shows 0 visitors
  • Real-time view empty
  • No data after 24 hours

Possible Causes & Solutions:

1. Using Excluded Domains

<!-- Check if your domain is excluded -->
<script src="https://cdn.usefathom.com/script.js"
        data-site="ABCDEFGH"
        data-excluded-domains="localhost,yourdomain.com"
        defer></script>

2. Wrong Site ID

<!-- Verify Site ID matches dashboard -->
<script src="https://cdn.usefathom.com/script.js"
        data-site="WRONGID"
        defer></script>

3. Firewall or Server Blocking Requests

  • Check server firewall settings
  • Verify outbound HTTPS allowed
  • Test from different network

4. Browser Privacy Settings

5. Script Loading After User Leaves

<!-- ❌ Wrong - async may load too late -->
<script async src="https://cdn.usefathom.com/script.js"></script>

<!-- ✅ Correct - defer loads before DOMContentLoaded -->
<script defer src="https://cdn.usefathom.com/script.js"></script>

SPA Pageviews Not Tracking

Symptoms:

  • First page loads correctly
  • Navigation doesn't trigger pageviews
  • Only one pageview per session

Possible Causes & Solutions:

1. Not Calling trackPageview() on Route Change

React Router:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function App() {
  const location = useLocation();

  useEffect(() => {
    if (window.fathom) {
      window.fathom.trackPageview();
    }
  }, [location]);

  return <div>...</div>;
}

Vue Router:

router.afterEach(() => {
  if (window.fathom) {
    window.fathom.trackPageview();
  }
});

Next.js:

import { useEffect } from 'react';
import { useRouter } from 'next/router';

function MyApp({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    function onRouteChange() {
      if (window.fathom) {
        window.fathom.trackPageview();
      }
    }

    router.events.on('routeChangeComplete', onRouteChange);
    return () => router.events.off('routeChangeComplete', onRouteChange);
  }, [router.events]);

  return <Component {...pageProps} />;
}

Data Not Appearing in Real-Time

Symptoms:

  • Events tracked successfully (network tab shows 200)
  • Data not showing in real-time dashboard
  • Data appears hours later

Possible Causes & Solutions:

1. Dashboard Not Refreshed

  • Click "Current visitors" in top right
  • Manually refresh the page
  • Real-time updates may take 10-30 seconds

2. Using Test/Development Domain

  • Verify you're viewing correct site in dashboard
  • Check if using excluded domains

3. Browser Cache

  • Hard refresh dashboard (Ctrl+F5 or Cmd+Shift+R)
  • Clear browser cache
  • Try incognito/private browsing

Custom Domain Not Working

Symptoms:

  • Script fails to load from custom domain
  • 404 errors on stats.yourdomain.com
  • Goals not tracking via custom domain

Possible Causes & Solutions:

1. DNS Not Configured Correctly

# Check DNS settings
# CNAME record should point to Fathom
stats.yourdomain.com -> cdn.usefathom.com

2. SSL Certificate Issues

  • Ensure SSL certificate covers subdomain
  • Check for mixed content warnings (HTTP/HTTPS)
  • Verify certificate is valid

3. Custom Domain Not Enabled in Fathom

  • Go to Settings > Custom Domain
  • Add and verify your domain
  • Wait for DNS propagation (up to 48 hours)

4. Incorrect Script Path

<!-- ❌ Wrong -->
<script src="https://stats.yourdomain.com/js/script.js" defer></script>

<!-- ✅ Correct -->
<script src="https://stats.yourdomain.com/script.js" defer></script>

Revenue Tracking Issues

Symptoms:

  • Goals tracking but revenue shows $0.00
  • Revenue values incorrect
  • API errors when tracking revenue

Possible Causes & Solutions:

1. Revenue Not in Cents

// ❌ Wrong - dollars with decimals
fathom.trackGoal('PURCHASE', 29.99);

// ✅ Correct - cents as integer
fathom.trackGoal('PURCHASE', 2999);

2. Revenue as String

// ❌ Wrong - string value
fathom.trackGoal('PURCHASE', '2999');

// ✅ Correct - integer value
fathom.trackGoal('PURCHASE', 2999);

3. Negative Values

// ❌ Wrong - negative not supported
fathom.trackGoal('REFUND', -2999);

// ✅ Use separate refund goal
fathom.trackGoal('REFUND', 0); // Track count only

4. Decimal Conversion Error

// ❌ Potential floating point error
const cents = price * 100; // 29.99 * 100 = 2999.0000000001

// ✅ Round to ensure integer
const cents = Math.round(price * 100); // 2999

Debugging Techniques

Browser Console Debugging

Check if Fathom is Loaded:

// In browser console
console.log(typeof fathom);
// Should output: "function"

// Check Fathom object
console.log(window.fathom);

Test Goal Tracking:

// Track test goal
fathom.trackGoal('TEST1234', 0);
console.log('Goal tracked');

// Check network tab for request

Test Pageview Tracking:

// Manually trigger pageview
fathom.trackPageview();
console.log('Pageview tracked');

Debug with Verbose Logging:

// Wrapper with logging
function debugTrackGoal(goalId, value = 0) {
  console.log('Tracking goal:', goalId, 'with value:', value);

  if (typeof fathom === 'undefined') {
    console.error('Fathom not loaded!');
    return;
  }

  try {
    fathom.trackGoal(goalId, value);
    console.log('Goal tracked successfully');
  } catch (error) {
    console.error('Goal tracking failed:', error);
  }
}

// Usage
debugTrackGoal('SIGNUP01', 0);

Network Tab Debugging

What to Look For:

  1. Script Loading:
Request URL: https://cdn.usefathom.com/script.js
Status: 200 OK
Type: script
  1. Pageview Tracking:
Request URL: https://cdn.usefathom.com/api/event
Status: 200 OK
Method: POST
Request Payload: {site: "ABCDEFGH", name: "pageview", ...}
  1. Goal Tracking:
Request URL: https://cdn.usefathom.com/api/event
Status: 200 OK
Method: POST
Request Payload: {site: "ABCDEFGH", name: "goal", goal: "SIGNUP01", value: 0}

Common Network Errors:

  • 0 (Failed): Request blocked by ad blocker or CSP
  • 403 Forbidden: Invalid Site ID
  • 404 Not Found: Incorrect script URL
  • Mixed Content: HTTP page loading HTTPS script (or vice versa)

Testing in Different Environments

Local Development:

<!-- Exclude localhost from tracking -->
<script src="https://cdn.usefathom.com/script.js"
        data-site="ABCDEFGH"
        data-excluded-domains="localhost,127.0.0.1"
        defer></script>

Staging Environment: Create separate Fathom site for staging:

<script src="https://cdn.usefathom.com/script.js"
        data-site="STAGING1"
        defer></script>

Production:

<script src="https://cdn.usefathom.com/script.js"
        data-site="ABCDEFGH"
        defer></script>

Environment-Based Setup:

// Next.js example
const FATHOM_SITE_ID = process.env.NEXT_PUBLIC_FATHOM_SITE_ID;

if (FATHOM_SITE_ID && typeof window !== 'undefined') {
  const script = document.createElement('script');
  script.src = 'https://cdn.usefathom.com/script.js';
  script.setAttribute('data-site', FATHOM_SITE_ID);
  script.defer = true;
  document.head.appendChild(script);
}

Real-Time Dashboard Monitoring

Steps:

  1. Open Fathom dashboard
  2. Click "Current visitors" (top right)
  3. Open your site in another tab
  4. Perform actions (pageviews, goals)
  5. Watch for events in real-time (refresh if needed)

What to Check:

  • Pageviews incrementing
  • Goals appearing under conversions
  • Revenue values displaying correctly
  • Referrer sources showing accurately

API Testing

Test Events API with cURL:

# Test pageview
curl -X POST https://cdn.usefathom.com/api/event \
  -H 'Content-Type: application/json' \
  -d '{
    "site": "ABCDEFGH",
    "name": "pageview",
    "url": "https://yourdomain.com/test"
  }'

# Test goal
curl -X POST https://cdn.usefathom.com/api/event \
  -H 'Content-Type: application/json' \
  -d '{
    "site": "ABCDEFGH",
    "name": "goal",
    "goal": "TEST1234",
    "value": 0
  }'

Expected Response:

Status: 200 OK
Body: (usually empty)

Performance Issues

Slow Page Loads

Symptoms:

  • Fathom script slowing down page load
  • Blocking rendering
  • Poor Lighthouse scores

Solutions:

1. Use defer Attribute:

<script src="https://cdn.usefathom.com/script.js" data-site="ABCDEFGH" defer></script>

2. Avoid async (less reliable):

<!-- ❌ May cause timing issues -->
<script async src="https://cdn.usefathom.com/script.js"></script>

3. Use Custom Domain for Speed:

<!-- Faster, same-domain loading -->
<script src="https://stats.yourdomain.com/script.js" data-site="ABCDEFGH" defer></script>

4. Check for Duplicate Scripts:

// Ensure only loaded once
if (!window.fathomLoaded) {
  window.fathomLoaded = true;
  // Load script
}

Too Many Events

Symptoms:

  • Hundreds of goal tracking calls
  • Inflated conversion numbers
  • Performance degradation

Solutions:

1. Debounce Frequent Events:

// Debounce helper
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func(...args), wait);
  };
}

// Use for scroll events, etc.
const trackScroll = debounce(() => {
  fathom.trackGoal('SCROLL', 0);
}, 1000);

window.addEventListener('scroll', trackScroll);

2. Track Only Once Per Session:

// Use sessionStorage to prevent duplicate tracking
function trackGoalOnce(goalId, value = 0) {
  const key = `fathom_tracked_${goalId}`;

  if (!sessionStorage.getItem(key)) {
    fathom.trackGoal(goalId, value);
    sessionStorage.setItem(key, 'true');
  }
}

// Usage
trackGoalOnce('WELCOME', 0);

3. Conditional Tracking:

// Only track significant actions
function trackSignificantScroll() {
  const scrollPercent = (window.scrollY / document.body.scrollHeight) * 100;

  if (scrollPercent > 75 && !window.scrollTracked) {
    fathom.trackGoal('SCROLL75', 0);
    window.scrollTracked = true;
  }
}

Getting Help

Before Contacting Support

  1. Check browser console for errors
  2. Verify network requests in DevTools
  3. Test in incognito mode
  4. Confirm Site ID is correct
  5. Check if goals exist in dashboard
  6. Review recent code changes
  7. Test with ad blocker disabled

Information to Provide

When contacting Fathom support, include:

  • Site ID: Found in Settings
  • Site URL: Where you're seeing issues
  • Browser and Version: Chrome 118, Safari 16, etc.
  • Error Messages: Console errors or API responses
  • Screenshots: Dashboard, console, network tab
  • Code Snippets: How you're implementing tracking
  • Steps to Reproduce: What actions trigger the issue

Support Resources

Best Practices to Avoid Issues

Implementation Checklist

  • Script uses defer attribute
  • Site ID is correct
  • Script placed in <head> section
  • Goals created in dashboard before tracking
  • Goal IDs match exactly (case-sensitive)
  • Revenue values in cents (integer)
  • SPA pageview tracking implemented
  • Error handling in place
  • Tested in multiple browsers
  • Real-time dashboard verified

Code Quality

Use Constants:

const FATHOM_GOALS = {
  SIGNUP: 'SIGNUP01',
  PURCHASE: 'PURCHASE',
  TRIAL: 'TRIAL123'
};

fathom.trackGoal(FATHOM_GOALS.SIGNUP, 0);

Centralize Tracking:

// analytics.js
export function trackGoal(goalId, value = 0) {
  if (window.fathom && typeof window.fathom.trackGoal === 'function') {
    try {
      window.fathom.trackGoal(goalId, value);
    } catch (error) {
      console.error('Fathom tracking error:', error);
    }
  }
}

Document Goal IDs:

/**
 * Fathom Goal IDs
 *
 * SIGNUP01 - Newsletter signup
 * PURCHASE - Product purchase (with revenue)
 * TRIAL123 - Trial signup
 * DOWNLOAD - Resource download
 */

Additional Resources:

// SYS.FOOTER