react-fathomv0.3.0
On this page
  1. Recommended Setup
  2. How It Works
  3. Configuration Options
  4. Props
  5. Alternative: Manual Setup
  6. Custom Client Component Wrapper
  7. Tracking Events
  8. Disabling Auto-Tracking
  9. Avoiding Duplicate Pageviews

App Router

Integrating react-fathom with Next.js App Router

Compatibility

Use this setup for Next.js 13.4+ projects with the app/ directory.

Use NextFathomProviderApp for the simplest setup. It combines the provider and automatic route tracking:

tsx
import { NextFathomProviderApp } from 'react-fathom/next'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <NextFathomProviderApp siteId="YOUR_SITE_ID">
          {children}
        </NextFathomProviderApp>
      </body>
    </html>
  )
}

That's it! Pageviews are now tracked automatically on every route change.

How It Works

NextFathomProviderApp is a Client Component (marked with 'use client') that:

  1. Wraps your app with FathomProvider
  2. Includes NextFathomTrackViewApp for automatic route tracking
  3. Can be used directly in Server Component layouts

Configuration Options

tsx
<NextFathomProviderApp
  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' }}
>
  {children}
</NextFathomProviderApp>

Props

PropTypeDescription
siteIdstringYour Fathom site ID
clientOptionsLoadOptionsOptions passed to fathom-client
defaultPageviewOptionsPageViewOptionsDefault options for all pageviews
defaultEventOptionsEventOptionsDefault options for all events
disableAutoTrackbooleanDisable automatic route tracking
childrenReactNodeYour app content

Alternative: Manual Setup

If you need more control, use FathomProvider with NextFathomTrackViewApp separately:

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

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <FathomProvider siteId="YOUR_SITE_ID" clientOptions={{ auto: false }}>
          <NextFathomTrackViewApp />
          {children}
        </FathomProvider>
      </body>
    </html>
  )
}

Since FathomProvider uses React hooks, you may need to wrap it in your own Client Component when using this approach directly in a Server Component layout.

Custom Client Component Wrapper

For advanced setups, create your own client component:

tsx
'use client'

import { FathomProvider } from 'react-fathom'
import { NextFathomTrackViewApp } from 'react-fathom/next'

export function AnalyticsProvider({ children }) {
  return (
    <FathomProvider
      siteId={process.env.NEXT_PUBLIC_FATHOM_SITE_ID}
      clientOptions={{ auto: false }}
    >
      <NextFathomTrackViewApp />
      {children}
    </FathomProvider>
  )
}
tsx
import { AnalyticsProvider } from '@/components/AnalyticsProvider'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AnalyticsProvider>{children}</AnalyticsProvider>
      </body>
    </html>
  )
}

Tracking Events

Use hooks and components in any Client Component:

tsx
'use client'

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
'use client'

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

export function CTASection() {
  return (
    <TrackVisible eventName="cta-section-viewed">
      <section>
        <h2>Ready to get started?</h2>
        <TrackClick eventName="cta-click">
          <button>Start Free Trial</button>
        </TrackClick>
      </section>
    </TrackVisible>
  )
}

Disabling Auto-Tracking

To handle pageview tracking manually:

tsx
<NextFathomProviderApp siteId="YOUR_SITE_ID" disableAutoTrack>
  {children}
</NextFathomProviderApp>

Then track pageviews where needed:

tsx
'use client'

import { useFathom } from 'react-fathom'
import { usePathname } from 'next/navigation'
import { useEffect } from 'react'

function CustomTracker() {
  const { trackPageview } = useFathom()
  const pathname = usePathname()

  useEffect(() => {
    // Custom logic before tracking
    if (pathname !== '/excluded-page') {
      trackPageview({ url: pathname })
    }
  }, [pathname, trackPageview])

  return null
}

Avoiding Duplicate Pageviews

The convenience provider and router HOCs disable the embed's automatic and SPA tracking while their router tracker is enabled. When composing a standalone provider with a tracker, disable embed tracking explicitly:

tsx
// Automatic composition owns pageview tracking.
<NextFathomProviderApp siteId="YOUR_SITE_ID">{children}</NextFathomProviderApp>

// CORRECT: Disable fathom-client's built-in auto tracking
<FathomProvider
  siteId="YOUR_SITE_ID"
  clientOptions={{ auto: false }}
>
  <NextFathomTrackViewApp />
  {children}
</FathomProvider>

Last updated: October 8, 2026

By

Commune Software