Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/frontend-v3/lib/components/navs/BuildNavLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
useDisclosure,
} from '@chakra-ui/react'
import { BuildPopover } from './BuildPopover'
import { AnalyticsEvent, trackEvent } from '@repo/lib/shared/services/fathom/Fathom'

export function BuildNavLink() {
const { isOpen, onOpen, onClose } = useDisclosure()
Expand Down Expand Up @@ -43,6 +44,7 @@ export function BuildNavLink() {
}, [isOpen, onClose])

const handleToggle = () => {
trackEvent(AnalyticsEvent.ClickNavBuild)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The track event code does not seem to differentiate between prod and the dev environments. That could probably skew the results a little.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Fathom.tsx on Line 60, it looks like Fathom is only tracking these domains, so I think dev environments are not being tracked, right? If not, I could use some help here.

cs 2025-10-21 at 17 07 03@2x

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see there is some code before that which mades it only run on prod:

// Optional: Only track on production; remove these two lines if you want to track other environments
if (!isProd) return

The zen.balancer.fi does not point to anything though, we can remove it.

if (isOpen) {
onClose()
} else {
Expand Down
7 changes: 6 additions & 1 deletion apps/frontend-v3/lib/components/navs/NavLogo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ import { BalancerLogoType } from '../imgs/BalancerLogoType'
import { Box, Link } from '@chakra-ui/react'
import { motion } from 'framer-motion'
import NextLink from 'next/link'
import { AnalyticsEvent, trackEvent } from '@repo/lib/shared/services/fathom/Fathom'

export function NavLogo() {
const handleLogoClick = () => {
trackEvent(AnalyticsEvent.ClickNavBalancerLogo)
}

return (
<Box as={motion.div} variants={fadeIn}>
<Link as={NextLink} href="/" prefetch variant="nav">
<Link as={NextLink} href="/" onClick={handleLogoClick} prefetch variant="nav">
<Box>
<Box display={{ base: 'block', md: 'none' }}>
<BalancerLogo width="26px" />
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/config/projects/balancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export const ProjectConfigBalancer: ProjectConfig = {
isOnSafeAppList: true,
},
links: {
appLinks: [{ href: '/vebal', label: 'veBAL' }],
appLinks: [{ analyticsEvent: 'ClickNavVeBal', href: '/vebal', label: 'veBAL' }],
ecosystemLinks: [
{ label: 'Pool creator', href: 'https://pool-creator.balancer.fi/' },
{ label: 'Blog', href: 'https://medium.com/balancer-protocol' },
Expand Down
18 changes: 16 additions & 2 deletions packages/lib/modules/pool/PoolList/PoolListFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import { isCowAmm, isBalancer, PROJECT_CONFIG } from '@repo/lib/config/getProjec
import { poolTypeLabel } from '../pool.helpers'
import { AnimatedTag } from '@repo/lib/shared/components/other/AnimatedTag'
import { PoolMinTvlFilter } from './PoolMinTvlFilter'
import { AnalyticsEvent, trackEvent } from '@repo/lib/shared/services/fathom/Fathom'

export function useFilterTagsVisible() {
const {
Expand Down Expand Up @@ -378,12 +379,24 @@ export function FilterTags({
}

export const FilterButton = forwardRef<ButtonProps & { totalFilterCount: number }, 'button'>(
({ totalFilterCount, ...props }, ref) => {
({ totalFilterCount, onClick, ...props }, ref) => {
const { isMobile } = useBreakpoints()
const textColor = useColorModeValue('#fff', 'font.dark')

const handleFilterClick = (e: React.MouseEvent<HTMLButtonElement>) => {
trackEvent(AnalyticsEvent.ClickPoolListFilter)
onClick?.(e)
}

return (
<Button ref={ref} {...props} display="flex" gap="2" variant="tertiary">
<Button
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The filters button doesn't seem to be working after this change, the handler function probably just eats the click event.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here: 22f7c8b

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why we have to do that (events should propagate unless otherwise stated), but it should do for now.

ref={ref}
{...props}
display="flex"
gap="2"
onClick={handleFilterClick}
variant="tertiary"
>
<Icon as={Filter} boxSize={4} />
{!isMobile && 'Filters'}
{totalFilterCount > 0 && (
Expand Down Expand Up @@ -634,6 +647,7 @@ export function PoolListFilters() {
href={poolCreatorUrl}
isExternal
ml="ms"
onClick={() => trackEvent(AnalyticsEvent.ClickPoolListCreatePool)}
variant="tertiary"
>
<Icon as={Plus} boxSize={4} />
Expand Down
8 changes: 7 additions & 1 deletion packages/lib/modules/user/UserFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@
import { Button } from '@chakra-ui/react'
import { ThumbsUp } from 'react-feather'
import { useAppzi } from '@repo/lib/shared/hooks/useAppzi'
import { AnalyticsEvent, trackEvent } from '@repo/lib/shared/services/fathom/Fathom'

export function UserFeedback() {
const { openNpsModal } = useAppzi()

const handleFeedbackClick = () => {
trackEvent(AnalyticsEvent.ClickNavUtilitiesFeedback)
openNpsModal()
}

return (
<Button onClick={openNpsModal} p="0" variant="tertiary">
<Button onClick={handleFeedbackClick} p="0" variant="tertiary">
<ThumbsUp size={18} />
</Button>
)
Expand Down
8 changes: 7 additions & 1 deletion packages/lib/modules/user/settings/UserSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { blockInvalidNumberInput } from '@repo/lib/shared/utils/numbers'
import { Percent, Settings } from 'react-feather'
import { CurrencySelect } from './CurrencySelect'
import { EnableTxBundleSetting } from './EnableTxBundlesSetting'
import { AnalyticsEvent, trackEvent } from '@repo/lib/shared/services/fathom/Fathom'
import { isBalancer } from '@repo/lib/config/getProjectConfig'

interface SlippageInputProps {
slippage: string
Expand Down Expand Up @@ -96,10 +98,14 @@ function ToggleAllowSounds() {
export function UserSettings() {
const { slippage, setSlippage } = useUserSettings()

const handleSettingsClick = () => {
if (isBalancer) trackEvent(AnalyticsEvent.ClickNavUtilitiesSettings)
}

return (
<Popover isLazy>
<PopoverTrigger>
<Button p="0" variant="tertiary">
<Button onClick={handleSettingsClick} p="0" variant="tertiary">
<Settings size={18} />
</Button>
</PopoverTrigger>
Expand Down
23 changes: 20 additions & 3 deletions packages/lib/modules/web3/ConnectWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { Box, Button, ButtonProps, HStack, Img, Show } from '@chakra-ui/react'
import { CustomAvatar } from './CustomAvatar'
import { useUserAccount } from './UserAccountProvider'
import { useIsSafeApp } from './safe.hooks'
import { AnalyticsEvent, trackEvent } from '@repo/lib/shared/services/fathom/Fathom'
import { isBalancer } from '@repo/lib/config/getProjectConfig'

export function ConnectWallet({
connectLabel = 'Connect wallet',
Expand Down Expand Up @@ -33,6 +35,11 @@ export function ConnectWallet({
(!authenticationStatus || authenticationStatus === 'authenticated')

if (!isConnected) {
const handleConnectClick = () => {
if (isBalancer) trackEvent(AnalyticsEvent.ClickNavUtilitiesWalletConnect)
openConnectModal()
}

return (
<HStack width="full">
{showCreateWalletButton && (
Expand All @@ -54,7 +61,7 @@ export function ConnectWallet({
<Button
isDisabled={isLoading || !mounted}
loadingText={connectLabel}
onClick={openConnectModal}
onClick={handleConnectClick}
type="button"
variant="primary"
{...rest}
Expand All @@ -79,13 +86,23 @@ export function ConnectWallet({
)
}

const handleNetworkClick = () => {
if (isBalancer) trackEvent(AnalyticsEvent.ClickNavUtilitiesNetwork)
openChainModal()
}

const handleWalletClick = () => {
if (isBalancer) trackEvent(AnalyticsEvent.ClickNavUtilitiesWalletChange)
openAccountModal()
}

return (
<HStack spacing="sm">
<Button
alignItems="center"
display="flex"
isDisabled={isSafeApp}
onClick={openChainModal}
onClick={handleNetworkClick}
type="button"
variant="tertiary"
{...rest}
Expand All @@ -110,7 +127,7 @@ export function ConnectWallet({
)}
<Show above="sm">{chain.name}</Show>
</Button>
<Button onClick={openAccountModal} variant="tertiary" {...rest} isDisabled={isSafeApp}>
<Button onClick={handleWalletClick} variant="tertiary" {...rest} isDisabled={isSafeApp}>
<CustomAvatar
address={account.address}
alt="Avatar"
Expand Down
3 changes: 3 additions & 0 deletions packages/lib/shared/components/btns/DarkModeToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import { AnimatePresence, motion } from 'framer-motion'
import { useTheme } from 'next-themes'
import { useEffect, useState } from 'react'
import { Moon, Sun } from 'react-feather'
import { AnalyticsEvent, trackEvent } from '../../services/fathom/Fathom'
import { isBalancer } from '@repo/lib/config/getProjectConfig'

export default function DarkModeToggle() {
const [mounted, setMounted] = useState(false)
const { theme, setTheme } = useTheme()
const { setColorMode } = useColorMode()

function toggleColorMode() {
if (isBalancer) trackEvent(AnalyticsEvent.ClickNavUtilitiesDarkmode)
setTheme(theme == 'light' ? 'dark' : 'light')
}

Expand Down
12 changes: 12 additions & 0 deletions packages/lib/shared/components/navs/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { isBalancer, isCowAmm } from '@repo/lib/config/getProjectConfig'
import { UserFeedback } from '@repo/lib/modules/user/UserFeedback'
import { ApiOutageAlert } from '../alerts/ApiOutageAlert'
import { useApiHealth } from '../../hooks/useApiHealth'
import { AnalyticsEvent, trackEvent } from '../../services/fathom/Fathom'

type Props = {
mobileNav?: ReactNode
Expand Down Expand Up @@ -61,6 +62,16 @@ function NavLinks({
}) {
const { linkColorFor } = useNav()

const handleLinkClick = (analyticsEvent?: string) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the code where we are tracking events is shared with Beets, do we want to track Beets events?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. We definitely do not want to track events from Beets.

I have updated the code to only track on Balancer events here :3c7a918

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is probably better to wrap the trackEvent function with our own one, so we don't have to add the if (isBalancer) ... logic everywhere.

if (
isBalancer &&
analyticsEvent &&
AnalyticsEvent[analyticsEvent as keyof typeof AnalyticsEvent]
) {
trackEvent(AnalyticsEvent[analyticsEvent as keyof typeof AnalyticsEvent])
}
}

return (
<HStack fontWeight="medium" spacing="lg" {...props}>
{appLinks.map(link => {
Expand All @@ -72,6 +83,7 @@ function NavLinks({
color={linkColorFor(link.href || '')}
href={link.href}
isExternal={link.isExternal}
onClick={() => handleLinkClick(link.analyticsEvent)}
prefetch
variant="nav"
>
Expand Down
4 changes: 4 additions & 0 deletions packages/lib/shared/components/navs/useNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export type AppLink = {
icon?: ReactNode
isExternal?: boolean
iconType?: IconType
analyticsEvent?: string
onClick?: () => void
}

Expand All @@ -19,14 +20,17 @@ export function useNav() {

const defaultAppLinks: AppLink[] = [
{
analyticsEvent: 'ClickNavPools',
href: '/pools',
label: 'Pools',
},
{
analyticsEvent: 'ClickNavSwap',
href: swapHref,
label: 'Swap',
},
{
analyticsEvent: 'ClickNavPortfolio',
href: '/portfolio',
label: 'Portfolio',
},
Expand Down
8 changes: 7 additions & 1 deletion packages/lib/shared/components/other/RecentTransactions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { getChainId, getChainShortName } from '@repo/lib/config/app.config'
import { getBlockExplorerTxUrl } from '../../utils/blockExplorer'
import { getSafeWebUrl } from '@repo/lib/modules/transactions/transaction-steps/safe/safe.helpers'
import { formatDistanceToNowAbbr } from '../../utils/time'
import { AnalyticsEvent, trackEvent } from '../../services/fathom/Fathom'
import { isBalancer } from '@repo/lib/config/getProjectConfig'

function TransactionIcon({ status }: { status: TransactionStatus }) {
switch (status) {
Expand Down Expand Up @@ -131,10 +133,14 @@ export default function RecentTransactions() {
tx => tx.status === 'confirming'
).length

const handleActivityClick = () => {
if (isBalancer) trackEvent(AnalyticsEvent.ClickNavUtilitiesActivity)
}

return (
<Popover>
<PopoverTrigger>
<Button p="0" variant="tertiary">
<Button onClick={handleActivityClick} p="0" variant="tertiary">
{confirmingTxCount > 0 ? (
<CircularProgress
color="font.warning"
Expand Down
19 changes: 17 additions & 2 deletions packages/lib/shared/services/fathom/Fathom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,24 @@ import { isProd } from '@repo/lib/config/app.config'

export enum AnalyticsEvent {
ClickAddLiquidity = 'click: Add liquidity',
TransactionSubmitted = 'transaction: Submitted',
ClickNavBalancerLogo = 'click: Primary nav Balancer logo',
ClickNavBuild = 'click: Build primary nav',
ClickNavPools = 'click: Pools primary nav',
ClickNavPortfolio = 'click: Portfolio primary nav',
ClickNavSwap = 'click: Swap primary nav',
ClickNavUtilitiesActivity = 'click: Nav utilities activity',
ClickNavUtilitiesDarkmode = 'click: Nav utilities darkmode',
ClickNavUtilitiesFeedback = 'click: Nav utilities feedback',
ClickNavUtilitiesNetwork = 'click: Nav utilities network',
ClickNavUtilitiesSettings = 'click: Nav utilities settings',
ClickNavUtilitiesWalletChange = 'click: Nav utilities wallet change',
ClickNavUtilitiesWalletConnect = 'click: Nav utilities wallet connect',
ClickNavVeBal = 'click: veBAL primary nav',
ClickPoolListCreatePool = 'click: Pool list create pool',
ClickPoolListFilter = 'click: Pool list filter',
TransactionConfirmed = 'transaction: Confirmed',
TransactionReverted = 'transaction: Reverted',
TransactionSubmitted = 'transaction: Submitted',
}

/**
Expand Down Expand Up @@ -42,7 +57,7 @@ function TrackPageView() {
load('MKFEFCXC', {
auto: false,
// Optional but I like to explicitly choose the domains to track:
includedDomains: ['balancer.fi', 'zen.balancer.fi'],
includedDomains: ['balancer.fi'],
})
}, [])

Expand Down
Loading