Refactor insights event props

This commit is contained in:
conico974
2025-06-18 10:09:22 +02:00
parent b4918f60ce
commit 0004d0228d
15 changed files with 140 additions and 45 deletions
+3 -3
View File
@@ -12,7 +12,7 @@ import * as React from 'react';
import { t, useLanguage } from '@/intl/client';
import { type ClassValue, tcls } from '@/lib/tailwind';
import { useTrackEvent } from '../Insights';
import { toSlimTrackEvent, useTrackEvent } from '../Insights';
import { useHasBeenInViewport } from '../hooks/useHasBeenInViewport';
import { Link } from '../primitives';
import { renderAd } from './renderAd';
@@ -137,10 +137,10 @@ function AdSponsoredLink(props: { spaceId: string }) {
target="_blank"
href={viaUrl.toString()}
className={tcls('hover:underline')}
insights={{
insights={toSlimTrackEvent({
type: 'trademark_click',
placement: SiteInsightsTrademarkPlacement.Ad,
}}
})}
>
{t(language, 'sponsored_via_gitbook')}
</Link>
@@ -2,6 +2,7 @@ import { type DocumentBlockContentRef, SiteInsightsLinkPosition } from '@gitbook
import { Card } from '@/components/primitives';
import { type ResolvedContentRef, resolveContentRef } from '@/lib/references';
import { toSlimTrackEvent } from '../Insights';
import type { BlockProps } from './Block';
@@ -34,13 +35,13 @@ export async function BlockContentRef(props: BlockProps<DocumentBlockContentRef>
href={resolved.href}
title={resolved.text}
style={style}
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: block.data.ref,
position: SiteInsightsLinkPosition.Content,
},
}}
})}
/>
);
}
@@ -1,5 +1,6 @@
import { resolveContentRef } from '@/lib/references';
import * as api from '@gitbook/api';
import { toSlimTrackEvent } from '../Insights';
import { Button } from '../primitives';
import type { InlineProps } from './Inline';
@@ -25,13 +26,13 @@ export async function InlineButton(props: InlineProps<api.DocumentInlineButton>)
// TODO: use a variant specifically for user-defined buttons.
variant={inline.data.kind}
className="leading-normal"
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: inline.data.ref,
position: api.SiteInsightsLinkPosition.Content,
},
}}
})}
/>
</span>
);
@@ -2,6 +2,7 @@ import { type DocumentInlineLink, SiteInsightsLinkPosition } from '@gitbook/api'
import { resolveContentRef } from '@/lib/references';
import { Icon } from '@gitbook/icons';
import { toSlimTrackEvent } from '../Insights';
import { StyledLink } from '../primitives';
import type { InlineProps } from './Inline';
import { InlineLinkTooltip } from './InlineLinkTooltip';
@@ -35,13 +36,13 @@ export async function InlineLink(props: InlineProps<DocumentInlineLink>) {
<InlineLinkTooltip inline={inline} context={context.contentContext} resolved={resolved}>
<StyledLink
href={resolved.href}
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: inline.data.ref,
position: SiteInsightsLinkPosition.Content,
},
}}
})}
>
<Inlines
context={context}
@@ -2,6 +2,7 @@ import { type DocumentInlineMention, SiteInsightsLinkPosition } from '@gitbook/a
import { StyledLink } from '@/components/primitives';
import { resolveContentRef } from '@/lib/references';
import { toSlimTrackEvent } from '../Insights';
import type { InlineProps } from './Inline';
@@ -21,13 +22,13 @@ export async function Mention(props: InlineProps<DocumentInlineMention>) {
return (
<StyledLink
href={resolved.href}
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: inline.data.ref,
position: SiteInsightsLinkPosition.Content,
},
}}
})}
>
{resolved.text}
</StyledLink>
@@ -8,6 +8,7 @@ import { LinkBox, LinkOverlay } from '@/components/primitives';
import { Image } from '@/components/utils';
import { resolveContentRef } from '@/lib/references';
import { type ClassValue, tcls } from '@/lib/tailwind';
import { toSlimTrackEvent } from '../../Insights';
import { RecordColumnValue } from './RecordColumnValue';
import type { TableRecordKV, TableViewProps } from './Table';
@@ -174,13 +175,13 @@ export async function RecordCard(
<LinkBox href={target.href} className={tcls(style, 'hover:before:ring-tint-12/5')}>
<LinkOverlay
href={target.href}
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: targetRef,
position: SiteInsightsLinkPosition.Content,
},
}}
})}
/>
{body}
</LinkBox>
@@ -15,6 +15,7 @@ import { getSimplifiedContentType } from '@/lib/files';
import { resolveContentRef } from '@/lib/references';
import { tcls } from '@/lib/tailwind';
import { filterOutNullable } from '@/lib/typescript';
import { toSlimTrackEvent } from '../../Insights';
import type { BlockProps } from '../Block';
import { Blocks } from '../Blocks';
@@ -275,13 +276,13 @@ export async function RecordColumnValue<Tag extends React.ElementType = 'div'>(
<StyledLink
key={index}
href={resolved.href}
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: contentRef,
position: SiteInsightsLinkPosition.Content,
},
}}
})}
>
{resolved.text}
</StyledLink>
@@ -7,6 +7,7 @@ import type { GitBookAnyContext } from '@v2/lib/context';
import { resolveContentRef } from '@/lib/references';
import { tcls } from '@/lib/tailwind';
import { toSlimTrackEvent } from '../Insights';
import { Link } from '../primitives';
@@ -58,13 +59,13 @@ async function FooterLink(props: { link: CustomizationContentLink; context: GitB
'links-accent:decoration-primary-subtle',
'links-accent:decoration-[3px]'
)}
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: link.to,
position: SiteInsightsLinkPosition.Footer,
},
}}
})}
>
{link.title}
</Link>
@@ -3,3 +3,4 @@ export * from './visitorId';
export * from './cookies';
export * from './TrackPageViewEvent';
export * from './useVisitedPages';
export * from './slimTrackEvent';
@@ -0,0 +1,99 @@
import type * as api from '@gitbook/api';
import type { InsightsEventName, TrackEventInput } from './InsightsProvider';
export type SlimTrackEventInput =
| { t: 'pv' }
| { t: 'so' }
| { t: 'stq'; q: string }
| { t: 'sor'; q: string; r: { s: string; p: string } }
| { t: 'ppf'; f: { r: api.PageFeedbackRating } }
| { t: 'ppfc'; f: { r: api.PageFeedbackRating; c: string } }
| { t: 'aq'; q: string }
| { t: 'lc'; l: { t: api.ContentRef; p: api.SiteInsightsLinkPosition } }
| { t: 'aco'; o: api.OpenAPIOperationPointer }
| { t: 'acr'; o: api.OpenAPIOperationPointer }
| { t: 'tc'; p: api.SiteInsightsTrademarkPlacement }
| { t: 'ac'; a: api.SiteInsightsAd }
| { t: 'ad'; a: api.SiteInsightsAd };
export function expandSlimTrackEvent(
input: SlimTrackEventInput
): TrackEventInput<InsightsEventName> {
switch (input.t) {
case 'pv':
return { type: 'page_view' };
case 'so':
return { type: 'search_open' };
case 'stq':
return { type: 'search_type_query', query: input.q };
case 'sor':
return {
type: 'search_open_result',
query: input.q,
result: { spaceId: input.r.s, pageId: input.r.p },
};
case 'ppf':
return { type: 'page_post_feedback', feedback: { rating: input.f.r } };
case 'ppfc':
return {
type: 'page_post_feedback_comment',
feedback: { rating: input.f.r, comment: input.f.c },
};
case 'aq':
return { type: 'ask_question', query: input.q };
case 'lc':
return {
type: 'link_click',
link: { target: input.l.t, position: input.l.p },
};
case 'aco':
return { type: 'api_client_open', operation: input.o };
case 'acr':
return { type: 'api_client_request', operation: input.o };
case 'tc':
return { type: 'trademark_click', placement: input.p };
case 'ac':
return { type: 'ad_click', ad: input.a };
case 'ad':
return { type: 'ad_display', ad: input.a };
default:
throw new Error('Unknown slim event');
}
}
export function toSlimTrackEvent(event: TrackEventInput<InsightsEventName>): SlimTrackEventInput {
switch (event.type) {
case 'page_view':
return { t: 'pv' };
case 'search_open':
return { t: 'so' };
case 'search_type_query':
return { t: 'stq', q: event.query };
case 'search_open_result':
return {
t: 'sor',
q: event.query,
r: { s: event.result.spaceId, p: event.result.pageId },
};
case 'page_post_feedback':
return { t: 'ppf', f: { r: event.feedback.rating } };
case 'page_post_feedback_comment':
return { t: 'ppfc', f: { r: event.feedback.rating, c: event.feedback.comment } };
case 'ask_question':
return { t: 'aq', q: event.query };
case 'link_click':
return { t: 'lc', l: { t: event.link.target, p: event.link.position } };
case 'api_client_open':
return { t: 'aco', o: event.operation };
case 'api_client_request':
return { t: 'acr', o: event.operation };
case 'trademark_click':
return { t: 'tc', p: event.placement };
case 'ad_click':
return { t: 'ac', a: event.ad };
case 'ad_display':
return { t: 'ad', a: event.ad };
default:
throw new Error('Unknown event type');
}
}
@@ -8,6 +8,7 @@ import type { GitBookAnyContext } from '@v2/lib/context';
import { Card } from '@/components/primitives';
import { resolveContentRef } from '@/lib/references';
import { tcls } from '@/lib/tailwind';
import { toSlimTrackEvent } from '../Insights';
import { PageIcon } from '../PageIcon';
@@ -48,13 +49,13 @@ export async function PageBodyBlankslate(props: {
leadingIcon={icon}
title={child.title}
href={resolved.href}
insights={{
insights={toSlimTrackEvent({
type: 'link_click',
link: {
target: child.target,
position: SiteInsightsLinkPosition.Content,
},
}}
})}
/>
);
}
@@ -32,9 +32,7 @@ export function PageFeedbackForm(props: {
trackEvent({
type: 'page_post_feedback',
feedback: {
rating,
},
feedback: { rating },
});
};
@@ -43,10 +41,7 @@ export function PageFeedbackForm(props: {
trackEvent({
type: 'page_post_feedback_comment',
feedback: {
rating,
comment,
},
feedback: { rating, comment },
});
};
@@ -2,6 +2,7 @@ import { tcls } from '@/lib/tailwind';
import { Icon, type IconName } from '@gitbook/icons';
import React from 'react';
import { toSlimTrackEvent } from '../Insights';
import { Link } from '../primitives';
import { HighlightQuery } from './HighlightQuery';
import type { ComputedPageResult } from './server-actions';
@@ -45,14 +46,11 @@ export const SearchPageResultItem = React.forwardRef(function SearchPageResultIt
? ['is-active', 'bg-primary', 'text-contrast-primary', 'hover:bg-primary-hover']
: null
)}
insights={{
insights={toSlimTrackEvent({
type: 'search_open_result',
query,
result: {
pageId: item.pageId,
spaceId: item.spaceId,
},
}}
result: { pageId: item.pageId, spaceId: item.spaceId },
})}
>
<div className="size-4">
<Icon
@@ -3,6 +3,7 @@ import React from 'react';
import { tcls } from '@/lib/tailwind';
import { toSlimTrackEvent } from '../Insights';
import { Link } from '../primitives';
import { HighlightQuery } from './HighlightQuery';
import type { ComputedSectionResult } from './server-actions';
@@ -40,14 +41,11 @@ export const SearchSectionResultItem = React.forwardRef(function SearchSectionRe
'hover:bg-primary-hover',
]
)}
insights={{
insights={toSlimTrackEvent({
type: 'search_open_result',
query,
result: {
pageId: item.pageId,
spaceId: item.spaceId,
},
}}
result: { pageId: item.pageId, spaceId: item.spaceId },
})}
>
<div
className={tcls(
@@ -4,7 +4,7 @@ import NextLink, { type LinkProps as NextLinkProps } from 'next/link';
import React from 'react';
import { tcls } from '@/lib/tailwind';
import { type TrackEventInput, useTrackEvent } from '../Insights';
import { type SlimTrackEventInput, expandSlimTrackEvent, useTrackEvent } from '../Insights';
// Props from Next, which includes NextLinkProps and all the things anchor elements support.
type BaseLinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof NextLinkProps> &
@@ -14,11 +14,7 @@ type BaseLinkProps = Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof N
export type LinkInsightsProps = {
/** Event to track when the link is clicked. */
insights?:
| TrackEventInput<'ad_click'>
| TrackEventInput<'link_click'>
| TrackEventInput<'trademark_click'>
| TrackEventInput<'search_open_result'>;
insights?: SlimTrackEventInput;
};
export type LinkProps = Omit<BaseLinkProps, 'href'> &
@@ -44,7 +40,7 @@ export const Link = React.forwardRef(function Link(
const onClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
if (insights) {
trackEvent(insights, undefined, {
trackEvent(expandSlimTrackEvent(insights), undefined, {
immediate: isExternal,
});
}