Fathom Analytics Gatsby Configuration
Fathom Analytics, a great tool to use for your site analytics without the compromise of giving your visitors data to Google.
I’ve written about How to Track Custom Events with Fathom in the past but since then Fathom have changed their tracking/embed code, which means the config is slightly different.
Install
With the new embed code there’s a guide on how to use the code with
Gatsby on Fathom’s blog. It involves modifying the Gatsby html.js
file which I’m not too keen on doing, although it works fine, it’s not
recommended.
I’ve gone with using React Helmet to add the embed code to the head of my Gatsby projects.
Add it as high up in the React component tree as possible. In my case
the way I do it is with the Gatsby wrapPageelEment
API which I use
in a module that’s shared between gatsby-browser.js
and
gatsby-ssr.js
.
There’s a Plugin for That
There’s also a plugin available, you can configure
gatsby-plugin-fathom
which will take the same details, a site id
and a custom domain but as far as I can tell it’s still using the
previous version of the embed code.
The new embed code is less verbose and offers some handy options like
enableTrackingForMe
and blockTrackingForMe
.
Here’s that same Fathom tracking from the Fathom blog guide, but I’m
adding it to the head of the site with React Helmet instead of using
the html.js
file.
1export const wrapPageElement = ({ element }) => (2 <>3 <Helmet>4 <script5 src={`${process.env.GATSBY_FATHOM_TRACKING_URL}/script.js`}6 spa="auto"7 site={process.env.GATSBY_FATHOM_TRACKING_ID}8 defer9 ></script>10 </Helmet>11 <MDXProvider components={components}>12 <Layout>{element}</Layout>13 </MDXProvider>14 </>15)
Track Events
Because the new tracking code is a tiny bit less verbose I’ve had to slightly modify the React Context Provider to accommodate.
1import React, { createContext, useContext } from 'react'2
3const AnalyticsContext = createContext({})4
5export const AnalyticsProvider = ({ children }) => {6 const logClicks = goalId => {7 window.fathom.trackGoal(goalId, 0)8 }9
10 return (11 <AnalyticsContext.Provider value={logClicks}>12 {children}13 </AnalyticsContext.Provider>14 )15}16
17export const useAnalytics = () => {18 return useContext(AnalyticsContext)19}
To consume the event tracking lower in the tree either use it with a
hardcoded goalId
or pass it in as a variable, here’s how I do it for
nav items.
1export const NavItems = () => {2 const fa = useAnalytics()3 return (4 <nav aria-label={`page navigation`}>5 <NavLink6 gridArea={`about`}7 href={`#hi-im-scott`}8 onClick={() => fa('GH6DDCV6')}9 >10 About11 </NavLink>12 <NavLink13 gridArea={`portfolio`}14 href={`#portfolio`}15 onClick={() => fa('HJAW5F8H')}16 >17 Portfolio18 </NavLink>19 ...
A click event passing in the goalId
there’s also the option to pass
a variable.
1export const A = props => {2 const fa = useAnalytics()3 const containsGoalId = props.href?.includes(`goalId`)4 const [goalId, setGoalId] = useState(``)5 const [newHref, setNewHref] = useState(``)6
7 useEffect(() => {8 if (containsGoalId) {9 const url = new URL(props.href)10 setGoalId(url.searchParams.get(`goalId`))11 url.searchParams.delete(`goalId`)12 setNewHref(url.href)13 }14 }, [containsGoalId, props.href])15
16 const onClick = () => {17 if (goalId) {18 fa(goalId, 0)19 }20 }21 return (22 <StyledA23 {...props}24 href={containsGoalId ? newHref : props.href}25 onClick={onClick}26 >27 {props.children}28 </StyledA>29 )30}
I’ve written before on how to Add Analytics Tracking Links to your
Markdown this still stands apart from there’s no need to include
quotes (""
) around the goalId
.
Back to Top