Fire embed:standardSite:view from feed viewability, not embed mount

Move the standard site view metric out of the embed (where it fired on
mount regardless of visibility) into PostFeed's onItemSeen handler, so it
only fires once per URI and only when the post is actually on screen,
matching the existing post:view and live:view:post tracking.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Eric Bailey
2026-06-04 17:06:31 -05:00
parent 2f61c0a7b4
commit 6754e89a74
2 changed files with 13 additions and 7 deletions
@@ -5,7 +5,6 @@ import {plural} from '@lingui/core/macro'
import {useLingui} from '@lingui/react/macro'
import {useHaptics} from '#/lib/haptics'
import {useCallOnce} from '#/lib/once'
import {shareUrl} from '#/lib/sharing'
import {niceDate} from '#/lib/strings/time'
import {toNiceDomain} from '#/lib/strings/url-helpers'
@@ -104,12 +103,6 @@ export const StandardSiteEmbed = ({
}
}
useCallOnce(() => {
if (!preview) {
ax.metric('embed:standardSite:view', {url: view.uri})
}
})()
if (isStandardPublication) {
return (
<PublicationCard
+13
View File
@@ -12,6 +12,7 @@ import {
} from 'react-native'
import {
type AppBskyActorDefs,
AppBskyEmbedExternal,
AppBskyEmbedVideo,
type AppBskyFeedDefs,
} from '@atproto/api'
@@ -58,6 +59,7 @@ import {
} from '#/components/feeds/PostFeedVideoGridRow'
import {TrendingInterstitial} from '#/components/interstitials/Trending'
import {TrendingVideos as TrendingVideosInterstitial} from '#/components/interstitials/TrendingVideos'
import {isStandardSiteEmbed} from '#/components/Post/Embed/StandardSiteEmbed/utils'
import {useAnalytics} from '#/analytics'
import {IS_IOS, IS_NATIVE, IS_WEB} from '#/env'
import {DiscoverFeedLiveEventFeedsAndTrendingBanner} from '#/features/liveEvents/components/DiscoverFeedLiveEventFeedsAndTrendingBanner'
@@ -905,6 +907,7 @@ let PostFeed = ({
const seenActorWithStatusRef = useRef<Set<string>>(new Set())
const seenPostUrisRef = useRef<Set<string>>(new Set())
const seenStandardSiteUrisRef = useRef<Set<string>>(new Set())
// Helper to calculate position in feed (count only root posts, not interstitials or thread replies)
const getPostPosition = useNonReactiveCallback(
@@ -974,6 +977,16 @@ let PostFeed = ({
})
}
}
// Standard site embed view tracking
if (
AppBskyEmbedExternal.isView(post.embed) &&
isStandardSiteEmbed(post.embed.external) &&
!seenStandardSiteUrisRef.current.has(post.embed.external.uri)
) {
seenStandardSiteUrisRef.current.add(post.embed.external.uri)
ax.metric('embed:standardSite:view', {url: post.embed.external.uri})
}
} else if (item.type === 'videoGridRow') {
// Track each video in the grid row
for (let i = 0; i < item.items.length; i++) {