Easily compose Fathom Analytics into your React/Next.js apps with automatic pageview tracking and full TypeScript support.
This package is designed to work with Fathom Analytics, a privacy-first website analytics platform. Fathom provides simple, GDPR-compliant analytics without cookies or tracking scripts that invade user privacy.
New to Fathom? Get a $10 credit on your first invoice when you sign up using this affiliate link. This helps support the development of this open-source package.
- π Zero-config Fathom Analytics integration for React
- π¦ Tree-shakeable - Only bundle what you use
- π Automatic pageview tracking for Next.js (Pages Router & App Router)
- πͺ Full TypeScript support with type definitions
- π― Flexible - Works with any React app or Next.js
- β‘ Lightweight - Minimal bundle size impact
Via npm
npm install react-fathom fathom-clientVia Yarn
yarn add react-fathom fathom-clientreact>= 16.8react-dom>= 16.8fathom-client>= 3.0.0next>= 10.0.0 (only if using Next.js providers)
Wrap your app with FathomProvider:
import { FathomProvider } from 'react-fathom'
function App() {
return <FathomProvider siteId="YOUR_SITE_ID">{/* Your app */}</FathomProvider>
}Access Fathom methods via the useFathom hook:
import { useFathom } from 'react-fathom'
function MyComponent() {
const { trackPageview, trackEvent, trackGoal, load } = useFathom()
const handleClick = () => {
trackEvent?.('button-click', { id: 'signup-button' })
}
const handlePurchase = () => {
trackGoal?.('purchase', 2999) // $29.99 in cents
}
return (
<>
<button onClick={handleClick}>Sign Up</button>
<button onClick={handlePurchase}>Buy Now</button>
</>
)
}Track events and pageviews with convenience hooks:
import {
useTrackOnMount,
useTrackOnClick,
useTrackOnVisible,
} from 'react-fathom'
function MyComponent() {
// Track pageview on mount
useTrackOnMount({ url: '/custom-page' })
// Track event on click
const handleClick = useTrackOnClick({
eventName: 'button-click',
id: 'signup-button',
callback: (e) => {
console.log('Tracked click!', e)
},
})
// Track event when element becomes visible
const ref = useTrackOnVisible({
eventName: 'section-viewed',
section: 'hero',
callback: (entry) => {
console.log('Element is visible!', entry)
},
})
return (
<>
<button onClick={handleClick}>Sign Up</button>
<div ref={ref}>This will be tracked when visible</div>
</>
)
}Use declarative components for tracking:
import { TrackPageview, TrackClick, TrackVisible } from 'react-fathom'
function MyPage() {
return (
<>
{/* Track pageview on mount */}
<TrackPageview url="/custom-page">
<div>Page content</div>
</TrackPageview>
{/* Track click events */}
<TrackClick eventName="button-click" id="signup-button">
<button>Sign Up</button>
</TrackClick>
{/* Track when element becomes visible */}
<TrackVisible eventName="section-viewed" section="hero">
<div>Hero section</div>
</TrackVisible>
</>
)
}Recommended: Use NextFathomProviderApp for easy integration in App Router layouts:
// app/layout.tsx
import { NextFathomProviderApp } from 'react-fathom/next'
export default function RootLayout({ children }) {
return (
<html>
<body>
<NextFathomProviderApp siteId="YOUR_SITE_ID">
{children}
</NextFathomProviderApp>
</body>
</html>
)
}Alternative: You can also use FathomProvider with NextFathomTrackViewApp separately if you need more control:
// app/layout.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">
<NextFathomTrackViewApp />
{children}
</FathomProvider>
</body>
</html>
)
}Note: Since
FathomProvideruses React hooks, you'll need to wrap it in a Client Component when using it directly in a Server Component layout.NextFathomProviderApphandles this for you automatically.
Use FathomProvider with NextFathomTrackViewPages for automatic route tracking:
// pages/_app.tsx
import { FathomProvider } from 'react-fathom'
import { NextFathomTrackViewPages } from 'react-fathom/next'
function MyApp({ Component, pageProps }) {
return (
<FathomProvider siteId="YOUR_SITE_ID">
<NextFathomTrackViewPages />
<Component {...pageProps} />
</FathomProvider>
)
}
export default MyAppMain provider component for React apps. Supports composable nesting - nested providers can override client, defaultPageviewOptions, or defaultEventOptions.
Props:
siteId(string, optional): Your Fathom Analytics site IDclient(FathomClient, optional): Custom Fathom client instanceclientOptions(LoadOptions, optional): Options passed tofathom-clientdefaultPageviewOptions(PageViewOptions, optional): Default options merged into alltrackPageviewcallsdefaultEventOptions(EventOptions, optional): Default options merged into alltrackEventcalls
Example:
<FathomProvider
siteId="YOUR_SITE_ID"
defaultPageviewOptions={{ referrer: 'https://example.com' }}
defaultEventOptions={{ id: 'global-id' }}
>
{/* Your app */}
</FathomProvider>Client component wrapper that combines FathomProvider and NextFathomTrackViewApp for easy integration in Next.js App Router layouts. This component is marked with 'use client' and can be used directly in Server Components like the root layout.tsx file.
Props:
siteId(string, optional): Your Fathom Analytics site IDclient(FathomClient, optional): Custom Fathom client instanceclientOptions(LoadOptions, optional): Options passed tofathom-clientdefaultPageviewOptions(PageViewOptions, optional): Default options merged into alltrackPageviewcallsdefaultEventOptions(EventOptions, optional): Default options merged into alltrackEventcallsdisableAutoTrack(boolean, optional): Disable automatic pageview tracking on route changes (defaults to false)children(ReactNode, required): Child components to render
Example:
// app/layout.tsx
import { NextFathomProviderApp } from 'react-fathom/next'
export default function RootLayout({ children }) {
return (
<html>
<body>
<NextFathomProviderApp siteId="YOUR_SITE_ID">
{children}
</NextFathomProviderApp>
</body>
</html>
)
}Component that tracks pageviews for Next.js App Router. Must be used within a FathomProvider.
Props:
disableAutoTrack(boolean, optional): Disable automatic pageview tracking on route changes (defaults to false)
Example:
<FathomProvider siteId="YOUR_SITE_ID">
<NextFathomTrackViewApp />
{/* Your app */}
</FathomProvider>Component that tracks pageviews for Next.js Pages Router. Must be used within a FathomProvider.
Props:
disableAutoTrack(boolean, optional): Disable automatic pageview tracking on route changes (defaults to false)
Example:
<FathomProvider siteId="YOUR_SITE_ID">
<NextFathomTrackViewPages />
{/* Your app */}
</FathomProvider>Hook to access Fathom methods and context.
Returns:
trackPageview(options?): Track a pageview (automatically mergesdefaultPageviewOptions)trackEvent(eventName, options?): Track a custom event (automatically mergesdefaultEventOptions)trackGoal(code, cents): Track a goal conversionload(siteId, options?): Load Fathom with a site IDsetSite(siteId): Change the site IDblockTrackingForMe(): Block tracking for current userenableTrackingForMe(): Enable tracking for current userisTrackingEnabled(): Check if tracking is enabledclient: The Fathom client instancedefaultPageviewOptions: Current default pageview optionsdefaultEventOptions: Current default event options
Hook to track a pageview when a component mounts.
Options:
url(string, optional): URL to trackreferrer(string, optional): Referrer URL- All other
PageViewOptionsfromfathom-client
Hook that returns a click handler function to track events.
Options:
eventName(string, required): Event name to trackpreventDefault(boolean, optional): Whether to prevent default behavior (defaults to false)callback((e?: MouseEvent) => void, optional): Callback function to run after tracking- All other
EventOptionsfromfathom-client
Hook that returns a ref to attach to an element. Tracks an event when the element becomes visible.
Options:
eventName(string, required): Event name to trackcallback((entry: IntersectionObserverEntry) => void, optional): Callback function to run after trackingthreshold(number, optional): IntersectionObserver threshold (defaults to 0.1)rootMargin(string, optional): IntersectionObserver rootMargin- All other
EventOptionsfromfathom-client
Component that tracks a pageview when it mounts.
Props:
url(string, optional): URL to trackreferrer(string, optional): Referrer URLchildren(ReactNode, optional): Child elements to render- All other
PageViewOptionsfromfathom-client
Component that tracks an event when clicked.
Props:
eventName(string, required): Event name to trackpreventDefault(boolean, optional): Whether to prevent default behavior (defaults to false)children(ReactNode, required): Child element(s) to render- All other
EventOptionsfromfathom-client
Component that tracks an event when it becomes visible.
Props:
eventName(string, required): Event name to trackthreshold(number, optional): IntersectionObserver threshold (defaults to 0.1)rootMargin(string, optional): IntersectionObserver rootMarginchildren(ReactNode, required): Child element(s) to renderas(string, optional): HTML element type to render (defaults to 'div')- All other
EventOptionsfromfathom-client
This library is optimized for tree-shaking. When you import only what you need:
import { useFathom } from 'react-fathom'Bundlers will automatically exclude unused code, keeping your bundle size minimal.
Full TypeScript support is included. Types are automatically generated and exported.
MIT Β© Ryan Hefner