react-fathomv0.3.0
On this page
  1. Setup
  2. Configuration Options
  3. FathomProvider Props
  4. NextFathomTrackViewPages Props
  5. Tracking Events
  6. Page-Specific Tracking
  7. Disabling Auto-Tracking
  8. Avoiding Duplicate Pageviews
  9. TypeScript

Pages Router

Integrate react-fathom with Next.js Pages Router.

Compatibility

Use this setup for projects with the pages/ directory.

Setup

Add the provider and route tracker to your _app.tsx:

tsx
import { FathomProvider } from 'react-fathom'
import { NextFathomTrackViewPages } from 'react-fathom/next'

function MyApp({ Component, pageProps }) {
  return (
    <FathomProvider siteId="YOUR_SITE_ID" clientOptions={{ auto: false }}>
      <NextFathomTrackViewPages />
      <Component {...pageProps} />
    </FathomProvider>
  )
}

export default MyApp

Pageviews are now tracked automatically on every route change.

Configuration Options

tsx
import { FathomProvider } from 'react-fathom'
import { NextFathomTrackViewPages } from 'react-fathom/next'

function MyApp({ Component, pageProps }) {
  return (
    <FathomProvider
      siteId="YOUR_SITE_ID"
      clientOptions={{
        includedDomains: ['yourdomain.com'],
        auto: false, // Disable fathom-client's built-in tracking
      }}
      defaultEventOptions={{ _site_id: 'my-app' }}
      defaultPageviewOptions={{ referrer: 'https://example.com' }}
    >
      <NextFathomTrackViewPages />
      <Component {...pageProps} />
    </FathomProvider>
  )
}

export default MyApp

FathomProvider Props

PropTypeDescription
siteIdstringYour Fathom site ID
clientOptionsLoadOptionsOptions passed to fathom-client
defaultPageviewOptionsPageViewOptionsDefault options for all pageviews
defaultEventOptionsEventOptionsDefault options for all events

NextFathomTrackViewPages Props

PropTypeDescription
disableAutoTrackbooleanDisable automatic route tracking

Tracking Events

Use hooks in any component:

tsx
import { useFathom } from 'react-fathom'

export function SignUpButton() {
  const { trackEvent } = useFathom()

  return <button onClick={() => trackEvent('signup-click')}>Sign Up</button>
}

Or use declarative components:

tsx
import { TrackClick, TrackVisible } from 'react-fathom'

export function PricingSection() {
  return (
    <TrackVisible eventName="pricing-viewed">
      <section>
        <h2>Pricing</h2>
        <TrackClick eventName="plan-selected" _value={999}>
          <button>Choose Pro Plan</button>
        </TrackClick>
      </section>
    </TrackVisible>
  )
}

Page-Specific Tracking

Track custom data on specific pages:

tsx
import { useTrackOnMount } from 'react-fathom'
import { useRouter } from 'next/router'

export default function ProductPage({ product }) {
  const router = useRouter()

  useTrackOnMount({
    url: `/product/${router.query.id}`,
    referrer: document.referrer,
  })

  return (
    <div>
      <h1>{product.name}</h1>
      {/* ... */}
    </div>
  )
}

Disabling Auto-Tracking

To handle pageview tracking manually:

tsx
<FathomProvider siteId="YOUR_SITE_ID" clientOptions={{ auto: false }}>
  <NextFathomTrackViewPages disableAutoTrack />
  <Component {...pageProps} />
</FathomProvider>

Then implement your own tracking logic:

tsx
import { useFathom } from 'react-fathom'
import { useRouter } from 'next/router'
import { useEffect } from 'react'

export function CustomTracker() {
  const { trackPageview } = useFathom()
  const router = useRouter()

  useEffect(() => {
    const handleRouteChange = (url) => {
      // Custom logic before tracking
      if (!url.startsWith('/admin')) {
        trackPageview({ url })
      }
    }

    router.events.on('routeChangeComplete', handleRouteChange)
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange)
    }
  }, [router.events, trackPageview])

  return null
}

Avoiding Duplicate Pageviews

If you see duplicate pageviews, disable fathom-client's built-in auto tracking:

tsx
<FathomProvider siteId="YOUR_SITE_ID" clientOptions={{ auto: false }}>
  <NextFathomTrackViewPages />
  <Component {...pageProps} />
</FathomProvider>

TypeScript

The Pages Router setup is fully typed:

tsx
import type { AppProps } from 'next/app'
import { FathomProvider } from 'react-fathom'
import { NextFathomTrackViewPages } from 'react-fathom/next'

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <FathomProvider siteId={process.env.NEXT_PUBLIC_FATHOM_SITE_ID!}>
      <NextFathomTrackViewPages />
      <Component {...pageProps} />
    </FathomProvider>
  )
}

export default MyApp

Last updated: October 8, 2026

By

Commune Software