diff --git a/packages/common/src/models/Analytics.ts b/packages/common/src/models/Analytics.ts
index 69dd1b6e1e8..cae82b2e5d9 100644
--- a/packages/common/src/models/Analytics.ts
+++ b/packages/common/src/models/Analytics.ts
@@ -308,6 +308,10 @@ export enum Name {
SEARCH_RESULT_SELECT = 'Search: Result Select',
SEARCH_TAB_CLICK = 'Search: Tab Click',
+ // Explore
+ EXPLORE_SECTION_VIEW = 'Explore: Section View',
+ EXPLORE_SECTION_CLICK = 'Explore: Section Click',
+
// Errors
ERROR_PAGE = 'Error Page',
NOT_FOUND_PAGE = 'Not Found Page',
@@ -1555,6 +1559,42 @@ type SearchResultSelect = {
kind: 'track' | 'profile' | 'playlist' | 'album'
}
+// Explore
+export type ExploreSectionName =
+ | 'Recommended Tracks'
+ | 'Artist Coin Tracks'
+ | 'Recently Played'
+ | 'Quick Search'
+ | 'Featured Playlists'
+ | 'Featured Remix Contests'
+ | 'Underground Trending Tracks'
+ | 'Artist Spotlight'
+ | 'Label Spotlight'
+ | 'Active Discussions'
+ | 'Downloads Available'
+ | 'Mood Grid'
+ | 'Trending Playlists'
+ | 'Most Shared'
+ | 'Best Selling'
+ | 'Recent Premium Tracks'
+ | 'Feeling Lucky'
+ | 'Recent Searches'
+
+type ExploreSectionView = {
+ eventName: Name.EXPLORE_SECTION_VIEW
+ section: ExploreSectionName
+ source: 'web' | 'mobile'
+}
+
+type ExploreSectionClick = {
+ eventName: Name.EXPLORE_SECTION_CLICK
+ section: ExploreSectionName
+ source: 'web' | 'mobile'
+ id?: ID
+ kind?: 'track' | 'profile' | 'playlist' | 'album' | 'mood' | 'preset'
+ link?: string
+}
+
type ListenGated = {
eventName: Name.LISTEN_GATED
trackId: string
@@ -3130,6 +3170,8 @@ export type AllTrackingEvents =
| SearchTag
| SearchMoreResults
| SearchResultSelect
+ | ExploreSectionView
+ | ExploreSectionClick
| ListenGated
| ErrorPage
| NotFoundPage
diff --git a/packages/mobile/src/screens/explore-screen/components/FeaturedArtistCoinTracks.tsx b/packages/mobile/src/screens/explore-screen/components/FeaturedArtistCoinTracks.tsx
index 1bcc9e4d148..7e71979c9a7 100644
--- a/packages/mobile/src/screens/explore-screen/components/FeaturedArtistCoinTracks.tsx
+++ b/packages/mobile/src/screens/explore-screen/components/FeaturedArtistCoinTracks.tsx
@@ -4,13 +4,14 @@ import { useExploreContent } from '@audius/common/api'
import { exploreMessages as messages } from '@audius/common/messages'
import { QueueSource } from '@audius/common/store'
-import { useDeferredElement } from '../../../hooks/useDeferredElement'
+import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'
import { ExploreSection } from './ExploreSection'
import { TrackTileCarousel } from './TrackTileCarousel'
export const FeaturedArtistCoinTracks = () => {
- const { InViewWrapper, inView } = useDeferredElement()
+ const { InViewWrapper, inView } =
+ useExploreSectionTracking('Artist Coin Tracks')
const { data, isPending } = useExploreContent({ enabled: inView })
return (
diff --git a/packages/mobile/src/screens/explore-screen/components/FeaturedPlaylists.tsx b/packages/mobile/src/screens/explore-screen/components/FeaturedPlaylists.tsx
index 9f1c0f352f1..0bf456d6856 100644
--- a/packages/mobile/src/screens/explore-screen/components/FeaturedPlaylists.tsx
+++ b/packages/mobile/src/screens/explore-screen/components/FeaturedPlaylists.tsx
@@ -6,13 +6,14 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { useTheme } from '@audius/harmony-native'
import { CollectionList } from 'app/components/collection-list'
-import { useDeferredElement } from '../../../hooks/useDeferredElement'
+import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'
import { ExploreSection } from './ExploreSection'
export const FeaturedPlaylists = () => {
const { spacing } = useTheme()
- const { InViewWrapper, inView } = useDeferredElement()
+ const { InViewWrapper, inView } =
+ useExploreSectionTracking('Featured Playlists')
const { data: exploreContent } = useExploreContent({ enabled: inView })
const { data: playlists } = useCollections(
diff --git a/packages/mobile/src/screens/explore-screen/components/ForYouTracks.tsx b/packages/mobile/src/screens/explore-screen/components/ForYouTracks.tsx
index 10d021a6096..9a34e5f2398 100644
--- a/packages/mobile/src/screens/explore-screen/components/ForYouTracks.tsx
+++ b/packages/mobile/src/screens/explore-screen/components/ForYouTracks.tsx
@@ -5,13 +5,14 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { QueueSource } from '@audius/common/store'
import { full } from '@audius/sdk'
-import { useDeferredElement } from 'app/hooks/useDeferredElement'
+import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'
import { ExploreSection } from './ExploreSection'
import { TrackTileCarousel } from './TrackTileCarousel'
export const ForYouTracks = () => {
- const { inView, InViewWrapper } = useDeferredElement()
+ const { inView, InViewWrapper } =
+ useExploreSectionTracking('Recommended Tracks')
const { data: recommendedTracks, isPending } = useRecommendedTracks(
{ pageSize: 10, timeRange: full.GetRecommendedTracksTimeEnum.Week },
{ enabled: inView }
diff --git a/packages/mobile/src/screens/explore-screen/components/MoodsGrid.tsx b/packages/mobile/src/screens/explore-screen/components/MoodsGrid.tsx
index f72bfb3c8d6..1c9952cf513 100644
--- a/packages/mobile/src/screens/explore-screen/components/MoodsGrid.tsx
+++ b/packages/mobile/src/screens/explore-screen/components/MoodsGrid.tsx
@@ -1,7 +1,9 @@
import React, { useMemo, useCallback } from 'react'
import { labelByCategory } from '@audius/common/api'
+import { useAnalytics } from '@audius/common/hooks'
import { exploreMessages as messages } from '@audius/common/messages'
+import { Name } from '@audius/common/models'
import type { Mood } from '@audius/sdk'
import { MOODS } from 'pages/search-page/moods'
import type { MoodInfo } from 'pages/search-page/types'
@@ -14,6 +16,7 @@ import {
useSearchCategory,
useSearchFilters
} from '../../search-screen/searchState.tsx'
+import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'
import { ExploreSection } from './ExploreSection.tsx'
@@ -22,9 +25,11 @@ interface MoodsGridProps {
}
export const MoodsGrid = ({ isLoading: externalLoading }: MoodsGridProps) => {
+ const { InViewWrapper } = useExploreSectionTracking('Mood Grid')
const { spacing } = useTheme()
const [category, setCategory] = useSearchCategory()
const [, setFilters] = useSearchFilters()
+ const { trackEvent } = useAnalytics()
const moodEntries = useMemo(
() => Object.entries(MOODS) as [string, MoodInfo][],
@@ -33,50 +38,59 @@ export const MoodsGrid = ({ isLoading: externalLoading }: MoodsGridProps) => {
const handleMoodPress = useCallback(
(moodLabel: Mood) => {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_CLICK,
+ section: 'Mood Grid',
+ source: 'mobile',
+ kind: 'mood',
+ link: moodLabel
+ })
if (category === 'all') {
setCategory('tracks')
}
setFilters({ mood: moodLabel })
},
- [setFilters, setCategory, category]
+ [setFilters, setCategory, category, trackEvent]
)
if (externalLoading) {
return null
}
return (
-
-
- {moodEntries.sort().map(([_, moodInfo]) => (
- {
- handleMoodPress(moodInfo.label)
- }}
- >
-
+
+
+ {moodEntries.sort().map(([_, moodInfo]) => (
+ {
+ handleMoodPress(moodInfo.label)
}}
- />
-
- {moodInfo.label}
-
-
- ))}
-
-
+ >
+
+
+ {moodInfo.label}
+
+
+ ))}
+
+
+
)
}
diff --git a/packages/mobile/src/screens/explore-screen/components/QuickSearchGrid.tsx b/packages/mobile/src/screens/explore-screen/components/QuickSearchGrid.tsx
index 5b487eebb08..fc790b53ff2 100644
--- a/packages/mobile/src/screens/explore-screen/components/QuickSearchGrid.tsx
+++ b/packages/mobile/src/screens/explore-screen/components/QuickSearchGrid.tsx
@@ -1,6 +1,8 @@
import React, { useCallback, useMemo } from 'react'
+import { useAnalytics } from '@audius/common/hooks'
import { exploreMessages as messages } from '@audius/common/messages'
+import { Name } from '@audius/common/models'
import {
QUICK_SEARCH_PRESETS,
type QuickSearchPreset
@@ -15,6 +17,7 @@ import {
useSearchCategory,
useSearchFilters
} from '../../search-screen/searchState.tsx'
+import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'
import { ExploreSection } from './ExploreSection.tsx'
@@ -102,11 +105,20 @@ const QuickSearchPresetButton = ({
}
export const QuickSearchGrid = () => {
+ const { InViewWrapper } = useExploreSectionTracking('Quick Search')
const [, setCategory] = useSearchCategory()
const [, setFilters] = useSearchFilters()
+ const { trackEvent } = useAnalytics()
const handlePressPreset = useCallback(
(preset: QuickSearchPreset) => {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_CLICK,
+ section: 'Quick Search',
+ source: 'mobile',
+ kind: 'preset',
+ link: `${preset.genre || ''}-${preset.mood || ''}-${preset.key || ''}`
+ })
// TODO: Support tabs
setCategory('tracks')
setFilters({
@@ -117,22 +129,24 @@ export const QuickSearchGrid = () => {
key: preset.key
})
},
- [setCategory, setFilters]
+ [setCategory, setFilters, trackEvent]
)
return (
-
-
- {QUICK_SEARCH_PRESETS.map((preset, idx) => (
- {
- handlePressPreset(preset)
- }}
- />
- ))}
-
-
+
+
+
+ {QUICK_SEARCH_PRESETS.map((preset, idx) => (
+ {
+ handlePressPreset(preset)
+ }}
+ />
+ ))}
+
+
+
)
}
diff --git a/packages/mobile/src/screens/explore-screen/components/RecentlyPlayed.tsx b/packages/mobile/src/screens/explore-screen/components/RecentlyPlayed.tsx
index 03042a85cec..18aa1c2826b 100644
--- a/packages/mobile/src/screens/explore-screen/components/RecentlyPlayed.tsx
+++ b/packages/mobile/src/screens/explore-screen/components/RecentlyPlayed.tsx
@@ -5,13 +5,14 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { useTheme } from '@audius/harmony-native'
import { TrackCardList } from 'app/components/track-card-list'
-import { useDeferredElement } from 'app/hooks/useDeferredElement'
+
+import { useExploreSectionTracking } from '../hooks/useExploreSectionTracking'
import { ExploreSection } from './ExploreSection'
export const RecentlyPlayedTracks = () => {
const { spacing } = useTheme()
- const { InViewWrapper, inView } = useDeferredElement()
+ const { InViewWrapper, inView } = useExploreSectionTracking('Recently Played')
const { data: recentlyPlayedTracks } = useRecentlyPlayedTracks(
{ pageSize: 10 },
{ enabled: inView }
diff --git a/packages/mobile/src/screens/explore-screen/hooks/useExploreSectionTracking.ts b/packages/mobile/src/screens/explore-screen/hooks/useExploreSectionTracking.ts
new file mode 100644
index 00000000000..14554fcea17
--- /dev/null
+++ b/packages/mobile/src/screens/explore-screen/hooks/useExploreSectionTracking.ts
@@ -0,0 +1,27 @@
+import { useEffect } from 'react'
+
+import { useAnalytics } from '@audius/common/hooks'
+import type { ExploreSectionName } from '@audius/common/models'
+import { Name } from '@audius/common/models'
+
+import { useDeferredElement } from 'app/hooks/useDeferredElement'
+
+/**
+ * Hook to track explore section impressions when they come into view on mobile
+ */
+export const useExploreSectionTracking = (sectionName: ExploreSectionName) => {
+ const { inView, InViewWrapper } = useDeferredElement()
+ const { trackEvent } = useAnalytics()
+
+ useEffect(() => {
+ if (inView) {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_VIEW,
+ section: sectionName,
+ source: 'mobile'
+ })
+ }
+ }, [inView, sectionName, trackEvent])
+
+ return { inView, InViewWrapper }
+}
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/ActiveDiscussionsSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/ActiveDiscussionsSection.tsx
index ba57b96ca0d..98dda5294af 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/ActiveDiscussionsSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/ActiveDiscussionsSection.tsx
@@ -3,10 +3,10 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const ActiveDiscussionsSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Active Discussions')
const { data, isLoading, isError, isSuccess } = useRecentlyCommentedTracks(
{ pageSize: 10 },
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/ArtistCoinTracksSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/ArtistCoinTracksSection.tsx
index a56279c7d73..0ed267abeb0 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/ArtistCoinTracksSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/ArtistCoinTracksSection.tsx
@@ -3,10 +3,10 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const ArtistCoinTracksSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Artist Coin Tracks')
const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/ArtistSpotlightSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/ArtistSpotlightSection.tsx
index efc79fd6c25..c8491ba69c9 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/ArtistSpotlightSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/ArtistSpotlightSection.tsx
@@ -5,10 +5,10 @@ import { UserCard, UserCardSkeleton } from 'components/user-card'
import { useIsMobile } from 'hooks/useIsMobile'
import { Carousel } from './Carousel'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const ArtistSpotlightSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Artist Spotlight')
const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
})
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/BestSellingSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/BestSellingSection.tsx
index c8b95e18ad7..ef0b7afd055 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/BestSellingSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/BestSellingSection.tsx
@@ -8,10 +8,10 @@ import { TrackCardSkeleton } from 'components/track/TrackCard'
import { useSearchCategory } from 'pages/search-page/hooks'
import { Carousel } from './Carousel'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const BestSellingSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Best Selling')
const [category] = useSearchCategory()
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/CollectionArtCard.tsx b/packages/web/src/pages/search-explore-page/components/desktop/CollectionArtCard.tsx
index b1f207b8b47..7e1e7cf042c 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/CollectionArtCard.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/CollectionArtCard.tsx
@@ -1,7 +1,13 @@
import { useCallback, useState } from 'react'
import { useCollection, useUser } from '@audius/common/api'
-import { ID, SquareSizes } from '@audius/common/models'
+import { useAnalytics } from '@audius/common/hooks'
+import {
+ ID,
+ SquareSizes,
+ ExploreSectionName,
+ Name
+} from '@audius/common/models'
import { Flex } from '@audius/harmony'
import { useNavigate } from 'react-router'
@@ -11,23 +17,47 @@ import { UserLink } from 'components/link/UserLink'
import PerspectiveCard from 'components/perspective-card/PerspectiveCard'
import { FavoriteStats } from 'components/stats/FavoriteStats'
import { RepostStats } from 'components/stats/RepostStats'
+import { useIsMobile } from 'hooks/useIsMobile'
import { UserListEntityType } from 'store/application/ui/userListModal/types'
type CollectionArtCardProps = {
id: ID
+ sectionName?: ExploreSectionName
}
const ARTWORK_SIZE = 240
-export const CollectionArtCard = ({ id }: CollectionArtCardProps) => {
+export const CollectionArtCard = ({
+ id,
+ sectionName
+}: CollectionArtCardProps) => {
const [isPerspectiveDisabled] = useState(false)
const navigate = useNavigate()
+ const { trackEvent } = useAnalytics()
+ const isMobile = useIsMobile()
const { data: partialCollection } = useCollection(id)
const goToPlaylist = useCallback(() => {
if (!partialCollection?.permalink) return
+ if (sectionName) {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_CLICK,
+ section: sectionName,
+ source: isMobile ? 'mobile' : 'web',
+ id,
+ kind: 'playlist',
+ link: partialCollection.permalink
+ })
+ }
navigate(partialCollection.permalink)
- }, [navigate, partialCollection?.permalink])
+ }, [
+ navigate,
+ partialCollection?.permalink,
+ sectionName,
+ id,
+ trackEvent,
+ isMobile
+ ])
const { data: user } = useUser(partialCollection?.playlist_owner_id)
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/DownloadsAvailableSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/DownloadsAvailableSection.tsx
index 55c7169d37a..dbffc78e312 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/DownloadsAvailableSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/DownloadsAvailableSection.tsx
@@ -6,10 +6,10 @@ import { QueueSource } from '@audius/common/store'
import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const DownloadsAvailableSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Downloads Available')
const {
data: lineupData,
isLoading,
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/FeaturedPlaylistsSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/FeaturedPlaylistsSection.tsx
index d6dd668b7f7..2677d92060b 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/FeaturedPlaylistsSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/FeaturedPlaylistsSection.tsx
@@ -5,10 +5,10 @@ import { CollectionCard, CollectionCardSkeleton } from 'components/collection'
import { useIsMobile } from 'hooks/useIsMobile'
import { Carousel } from './Carousel'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const FeaturedPlaylistsSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Featured Playlists')
const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/FeaturedRemixContestsSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/FeaturedRemixContestsSection.tsx
index 2edcff8bbfc..2eb0f9cbff1 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/FeaturedRemixContestsSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/FeaturedRemixContestsSection.tsx
@@ -8,10 +8,10 @@ import {
import { useIsMobile } from 'hooks/useIsMobile'
import { Carousel } from './Carousel'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const FeaturedRemixContestsSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Featured Remix Contests')
const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/FeelingLuckySection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/FeelingLuckySection.tsx
index 477fb1295e2..a5d2280882e 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/FeelingLuckySection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/FeelingLuckySection.tsx
@@ -13,10 +13,10 @@ import { TrackTile as MobileTrackTile } from 'components/track/mobile/TrackTile'
import { TrackTileSize } from 'components/track/types'
import { useIsMobile } from 'hooks/useIsMobile'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const FeelingLuckySection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Feeling Lucky')
const isMobile = useIsMobile()
const {
data: feelingLuckyTrack,
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/LabelSpotlightSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/LabelSpotlightSection.tsx
index ecd1f2d0789..54798769302 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/LabelSpotlightSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/LabelSpotlightSection.tsx
@@ -5,10 +5,10 @@ import { UserCard, UserCardSkeleton } from 'components/user-card'
import { useIsMobile } from 'hooks/useIsMobile'
import { Carousel } from './Carousel'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const LabelSpotlightSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Label Spotlight')
const { data, isLoading, isError, isSuccess } = useExploreContent({
enabled: inView
})
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/MoodGrid.tsx b/packages/web/src/pages/search-explore-page/components/desktop/MoodGrid.tsx
index 0d24b55f6cb..bbb16dd0472 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/MoodGrid.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/MoodGrid.tsx
@@ -1,6 +1,8 @@
import { useCallback } from 'react'
+import { useAnalytics } from '@audius/common/hooks'
import { exploreMessages as messages } from '@audius/common/messages'
+import { Name } from '@audius/common/models'
import { Flex, Paper, Text, useTheme } from '@audius/harmony'
import { Mood } from '@audius/sdk'
@@ -9,25 +11,37 @@ import { useSearchCategory } from 'pages/search-page/hooks'
import { labelByCategoryView } from 'pages/search-page/types'
import { MOODS } from 'utils/Moods'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
+
export const MoodGrid = () => {
+ const { ref } = useExploreSectionTracking('Mood Grid')
const [category, setCategory] = useSearchCategory()
const { color } = useTheme()
+ const { trackEvent } = useAnalytics()
const isMobile = useIsMobile()
const handleMoodPress = useCallback(
(mood: Mood) => {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_CLICK,
+ section: 'Mood Grid',
+ source: isMobile ? 'mobile' : 'web',
+ kind: 'mood',
+ link: mood
+ })
if (category === 'all') {
setCategory('tracks', { mood })
} else {
setCategory(category, { mood })
}
},
- [category, setCategory]
+ [category, setCategory, trackEvent, isMobile]
)
return (
{
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Most Shared')
const { data, isLoading, isError, isSuccess } = useMostSharedTracks(
{
pageSize: 10,
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/QuickSearchGrid.tsx b/packages/web/src/pages/search-explore-page/components/desktop/QuickSearchGrid.tsx
index bbce30b8817..fc69f1589b7 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/QuickSearchGrid.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/QuickSearchGrid.tsx
@@ -1,6 +1,8 @@
import React, { useCallback, useMemo } from 'react'
+import { useAnalytics } from '@audius/common/hooks'
import { exploreMessages as messages } from '@audius/common/messages'
+import { Name } from '@audius/common/models'
import {
QUICK_SEARCH_PRESETS,
QuickSearchPreset,
@@ -12,15 +14,24 @@ import { useIsMobile } from 'hooks/useIsMobile'
import { useSearchCategory } from 'pages/search-page/hooks'
import { MOODS } from 'utils/Moods'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
+
const QuickSearchPresetButton = ({
preset,
- onClick
+ onClick,
+ onTrackClick
}: {
preset: QuickSearchPreset
onClick: () => void
+ onTrackClick: () => void
}) => {
const { color } = useTheme()
+ const handleClick = useCallback(() => {
+ onTrackClick()
+ onClick()
+ }, [onClick, onTrackClick])
+
const parts = useMemo(() => {
const parts: React.ReactNode[] = []
if (preset.genre) {
@@ -72,7 +83,7 @@ const QuickSearchPresetButton = ({
gap='s'
border='default'
backgroundColor='white'
- onClick={onClick}
+ onClick={handleClick}
css={{
':hover': {
background: color.neutral.n25,
@@ -101,11 +112,20 @@ const QuickSearchPresetButton = ({
}
export const QuickSearchGrid = () => {
+ const { ref } = useExploreSectionTracking('Quick Search')
const isMobile = useIsMobile()
const [, setCategory] = useSearchCategory()
+ const { trackEvent } = useAnalytics()
const handleClickPreset = useCallback(
(preset: QuickSearchPreset) => {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_CLICK,
+ section: 'Quick Search',
+ source: isMobile ? 'mobile' : 'web',
+ kind: 'preset',
+ link: `${preset.genre || ''}-${preset.mood || ''}-${preset.key || ''}`
+ })
setCategory('tracks', {
mood: preset.mood,
genre: preset.genre,
@@ -114,11 +134,12 @@ export const QuickSearchGrid = () => {
key: preset.key
})
},
- [setCategory]
+ [setCategory, trackEvent, isMobile]
)
return (
{
handleClickPreset(preset)}
+ onTrackClick={() => {}}
preset={preset}
/>
))}
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/RecentPremiumTracksSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/RecentPremiumTracksSection.tsx
index fabe0ffa751..fc570ae0fac 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/RecentPremiumTracksSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/RecentPremiumTracksSection.tsx
@@ -3,10 +3,10 @@ import { exploreMessages as messages } from '@audius/common/messages'
import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const RecentPremiumTracksSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Recent Premium Tracks')
const { data, isLoading, isError, isSuccess } = useRecentPremiumTracks(
{ pageSize: 10 },
{ enabled: inView }
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/RecentSearchesSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/RecentSearchesSection.tsx
index ae4dd6b9c76..8bd91ffa43d 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/RecentSearchesSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/RecentSearchesSection.tsx
@@ -3,10 +3,10 @@ import { Flex } from '@audius/harmony'
import { useIsMobile } from 'hooks/useIsMobile'
import { RecentSearches } from 'pages/search-page/RecentSearches'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const RecentSearchesSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Recent Searches')
const isMobile = useIsMobile()
return (
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/RecentlyPlayedSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/RecentlyPlayedSection.tsx
index 5129f05ffea..e4a8ea2a399 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/RecentlyPlayedSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/RecentlyPlayedSection.tsx
@@ -5,10 +5,10 @@ import { TrackCard, TrackCardSkeleton } from 'components/track/TrackCard'
import { useIsMobile } from 'hooks/useIsMobile'
import { Carousel } from './Carousel'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const RecentlyPlayedSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Recently Played')
const { data, isLoading, isError, isSuccess } = useRecentlyPlayedTracks(
{ pageSize: 10 },
{ enabled: inView }
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/RecommendedTracksSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/RecommendedTracksSection.tsx
index a066ba8433e..7931dd42ff6 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/RecommendedTracksSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/RecommendedTracksSection.tsx
@@ -4,10 +4,10 @@ import { full } from '@audius/sdk'
import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const RecommendedTracksSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Recommended Tracks')
const { data, isLoading, isError, isSuccess } = useRecommendedTracks(
{
pageSize: 10,
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/TrackArtCard.tsx b/packages/web/src/pages/search-explore-page/components/desktop/TrackArtCard.tsx
index f329a006a77..03744f91c30 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/TrackArtCard.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/TrackArtCard.tsx
@@ -1,7 +1,13 @@
import { useCallback } from 'react'
import { useRemixContest, useTrack } from '@audius/common/api'
-import { ID, SquareSizes } from '@audius/common/models'
+import { useAnalytics } from '@audius/common/hooks'
+import {
+ ID,
+ SquareSizes,
+ ExploreSectionName,
+ Name
+} from '@audius/common/models'
import { dayjs, formatContestDeadlineWithStatus } from '@audius/common/utils'
import { Flex, Skeleton, Text } from '@audius/harmony'
import { useNavigate } from 'react-router'
@@ -10,9 +16,11 @@ import { TrackLink } from 'components/link/TrackLink'
import { UserLink } from 'components/link/UserLink'
import PerspectiveCard from 'components/perspective-card/PerspectiveCard'
import { TrackArtwork } from 'components/track/TrackArtwork'
+import { useIsMobile } from 'hooks/useIsMobile'
type TrackArtCardProps = {
id: ID
+ sectionName?: ExploreSectionName
}
const messages = {
@@ -29,8 +37,10 @@ const messages = {
const ARTWORK_SIZE = 240
-export const TrackArtCard = ({ id }: TrackArtCardProps) => {
+export const TrackArtCard = ({ id, sectionName }: TrackArtCardProps) => {
const navigate = useNavigate()
+ const { trackEvent } = useAnalytics()
+ const isMobile = useIsMobile()
const { data: track, isLoading: isTrackLoading } = useTrack(id)
const { data: contest, isLoading: isContestLoading } = useRemixContest(id)
@@ -39,8 +49,18 @@ export const TrackArtCard = ({ id }: TrackArtCardProps) => {
const goToTrack = useCallback(() => {
if (!track?.permalink) return
+ if (sectionName) {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_CLICK,
+ section: sectionName,
+ source: isMobile ? 'mobile' : 'web',
+ id,
+ kind: 'track',
+ link: track.permalink
+ })
+ }
navigate(track.permalink)
- }, [navigate, track?.permalink])
+ }, [navigate, track?.permalink, sectionName, id, trackEvent, isMobile])
if (!track) return null
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/TrendingPlaylistsSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/TrendingPlaylistsSection.tsx
index 2ca65ab9c2e..b400fd2e7ac 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/TrendingPlaylistsSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/TrendingPlaylistsSection.tsx
@@ -17,7 +17,7 @@ import {
MOBILE_TILE_WIDTH,
TILE_WIDTH
} from './constants'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
type TileType = typeof DesktopCollectionTile | typeof MobileCollectionTile
@@ -119,7 +119,7 @@ const CollectionLineupCarousel = ({
}
export const TrendingPlaylistsSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking('Trending Playlists')
const isMobile = useIsMobile()
const size = isMobile ? TrackTileSize.SMALL : TrackTileSize.LARGE
const { lineup, isError, isSuccess, isLoading, play, pause, togglePlay } =
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/UndergroundTrendingTracksSection.tsx b/packages/web/src/pages/search-explore-page/components/desktop/UndergroundTrendingTracksSection.tsx
index d5b5d1e108b..ad03c21d18e 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/UndergroundTrendingTracksSection.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/UndergroundTrendingTracksSection.tsx
@@ -6,10 +6,12 @@ import { Status } from '@audius/common/models'
import { Carousel } from './Carousel'
import { TilePairs, TileSkeletons } from './TileHelpers'
-import { useDeferredElement } from './useDeferredElement'
+import { useExploreSectionTracking } from './useExploreSectionTracking'
export const UndergroundTrendingTracksSection = () => {
- const { ref, inView } = useDeferredElement()
+ const { ref, inView } = useExploreSectionTracking(
+ 'Underground Trending Tracks'
+ )
const {
data: undergroundTrendingTracks,
isLoading,
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/UserArtCard.tsx b/packages/web/src/pages/search-explore-page/components/desktop/UserArtCard.tsx
index 5b68ed06a18..62a50119e6a 100644
--- a/packages/web/src/pages/search-explore-page/components/desktop/UserArtCard.tsx
+++ b/packages/web/src/pages/search-explore-page/components/desktop/UserArtCard.tsx
@@ -2,7 +2,13 @@ import { useCallback, useEffect } from 'react'
import { useUser } from '@audius/common/api'
import { imageBlank as placeholderArt } from '@audius/common/assets'
-import { SquareSizes, ID } from '@audius/common/models'
+import { useAnalytics } from '@audius/common/hooks'
+import {
+ SquareSizes,
+ ID,
+ ExploreSectionName,
+ Name
+} from '@audius/common/models'
import { formatCount, route } from '@audius/common/utils'
import cn from 'classnames'
import { connect } from 'react-redux'
@@ -38,6 +44,7 @@ type OwnProps = {
index: number
isLoading?: boolean
setDidLoad?: (index: number) => void
+ sectionName?: ExploreSectionName
}
type UserArtCardProps = OwnProps &
@@ -58,14 +65,27 @@ const UserArtCard = g(
user,
setFollowerUser,
setModalVisibility,
- goToRoute
+ goToRoute,
+ sectionName
}) => {
const { user_id, name, handle, follower_count } = user
+ const { trackEvent } = useAnalytics()
+ const isMobile = typeof window !== 'undefined' && window.innerWidth < 768
const goToProfile = useCallback(() => {
+ if (sectionName) {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_CLICK,
+ section: sectionName,
+ source: isMobile ? 'mobile' : 'web',
+ id: user_id,
+ kind: 'profile',
+ link: profilePage(handle)
+ })
+ }
const link = profilePage(handle)
goToRoute(link)
- }, [handle, goToRoute])
+ }, [handle, goToRoute, sectionName, user_id, trackEvent, isMobile])
const onClickFollowers = useCallback(() => {
setFollowerUser(user_id)
diff --git a/packages/web/src/pages/search-explore-page/components/desktop/useExploreSectionTracking.ts b/packages/web/src/pages/search-explore-page/components/desktop/useExploreSectionTracking.ts
new file mode 100644
index 00000000000..b5237ea450b
--- /dev/null
+++ b/packages/web/src/pages/search-explore-page/components/desktop/useExploreSectionTracking.ts
@@ -0,0 +1,29 @@
+import { useEffect } from 'react'
+
+import { useAnalytics } from '@audius/common/hooks'
+import { ExploreSectionName, Name } from '@audius/common/models'
+
+import { useIsMobile } from 'hooks/useIsMobile'
+
+import { useDeferredElement } from './useDeferredElement'
+
+/**
+ * Hook to track explore section impressions when they come into view
+ */
+export const useExploreSectionTracking = (sectionName: ExploreSectionName) => {
+ const { ref, inView } = useDeferredElement()
+ const { trackEvent } = useAnalytics()
+ const isMobile = useIsMobile()
+
+ useEffect(() => {
+ if (inView) {
+ trackEvent({
+ eventName: Name.EXPLORE_SECTION_VIEW,
+ section: sectionName,
+ source: isMobile ? 'mobile' : 'web'
+ })
+ }
+ }, [inView, sectionName, isMobile, trackEvent])
+
+ return { ref, inView }
+}