chore: Add telemetry to search v2 user actions

This commit is contained in:
Jeremias Menichelli committed 2026-10-01 16:00:51 -03:00
1 parent be976bec49
commit d647c8a0e7
3 files changed
+103 -5

No files matched your search

+11 -1
View File
@@ -19,6 +19,7 @@ import {
} from 'ui'
import { formatHeadingPath, highlightMatches } from './SearchV2.utils'
import { useSendTelemetryEvent } from '@/lib/telemetry'
interface SearchV2DialogProps {
open: boolean
@@ -27,6 +28,7 @@ interface SearchV2DialogProps {
export function SearchV2Dialog({ open, onOpenChange }: SearchV2DialogProps) {
const router = useRouter()
const sendTelemetryEvent = useSendTelemetryEvent()
const { searchState, handleDocsSearchDebounced, resetSearch } = useDocsSearchV2()
const [highlightQuery, setHighlightQuery] = useState('')
@@ -40,10 +42,14 @@ export function SearchV2Dialog({ open, onOpenChange }: SearchV2DialogProps) {
useEffect(() => {
if (searchState.status === 'results' || searchState.status === 'noResults') {
setHighlightQuery(searchState.query)
sendTelemetryEvent({
action: 'docs_search_v2_search_submitted',
properties: { query: searchState.query },
})
} else if (searchState.status === 'initial') {
setHighlightQuery('')
}
}, [searchState])
}, [searchState, sendTelemetryEvent])
const results: DocsSearchV2Result[] =
'results' in searchState
@@ -61,6 +67,10 @@ export function SearchV2Dialog({ open, onOpenChange }: SearchV2DialogProps) {
}
function handleSelect(path: string) {
sendTelemetryEvent({
action: 'docs_search_v2_result_clicked',
properties: { resultPath: path, query: highlightQuery },
})
router.push(path)
onOpenChange(false)
}
@@ -1,10 +1,11 @@
'use client'
import { Search } from 'lucide-react'
import { useEffect, useState, type ReactNode } from 'react'
import { useCallback, useEffect, useState, type ReactNode } from 'react'
import { cn, KeyboardShortcut } from 'ui'
import { SearchV2Dialog } from './SearchV2Dialog'
import { useSendTelemetryEvent } from '@/lib/telemetry'
interface SearchV2TriggerProps {
className?: string
@@ -13,6 +14,17 @@ interface SearchV2TriggerProps {
export function SearchV2Trigger({ className, placeholder = 'Search...' }: SearchV2TriggerProps) {
const [open, setOpen] = useState(false)
const sendTelemetryEvent = useSendTelemetryEvent()
const handleOpenChange = useCallback(
(next: boolean) => {
setOpen(next)
if (!next) {
sendTelemetryEvent({ action: 'docs_search_v2_closed' })
}
},
[sendTelemetryEvent]
)
useEffect(() => {
function openOnKeyDown(event: globalThis.KeyboardEvent) {
@@ -25,6 +37,10 @@ export function SearchV2Trigger({ className, placeholder = 'Search...' }: Search
event.preventDefault()
setOpen(true)
sendTelemetryEvent({
action: 'docs_search_v2_opened',
properties: { triggerType: 'keyboard_shortcut' },
})
}
}
@@ -33,7 +49,7 @@ export function SearchV2Trigger({ className, placeholder = 'Search...' }: Search
return () => {
window.removeEventListener('keydown', openOnKeyDown, { capture: true })
}
}, [])
}, [sendTelemetryEvent])
return (
<>
@@ -42,7 +58,13 @@ export function SearchV2Trigger({ className, placeholder = 'Search...' }: Search
tabIndex={0}
aria-haspopup="dialog"
aria-expanded={open}
onClick={() => setOpen(true)}
onClick={() => {
setOpen(true)
sendTelemetryEvent({
action: 'docs_search_v2_opened',
properties: { triggerType: 'search_input' },
})
}}
className={cn(
'group cursor-pointer',
'grow md:min-w-44 xl:min-w-56 h-[30px] rounded-md',
@@ -69,7 +91,7 @@ export function SearchV2Trigger({ className, placeholder = 'Search...' }: Search
className="hidden md:inline-flex border border-default bg-surface-300 text-foreground-lighter shadow-xs shadow-background-surface-100"
/>
</button>
<SearchV2Dialog open={open} onOpenChange={setOpen} />
<SearchV2Dialog open={open} onOpenChange={handleOpenChange} />
</>
)
}
+66
View File
@@ -1075,6 +1075,68 @@ export interface DocsContentListingClickedEvent {
}
}
/**
* User opened the Search V2 dialog.
*
* @group Events
* @source docs
*/
export interface DocsSearchV2OpenedEvent {
action: 'docs_search_v2_opened'
properties: {
/**
* The trigger that opened the Search V2 dialog.
*/
triggerType: 'keyboard_shortcut' | 'search_input'
}
}
/**
* User's search term was sent to the Search V2 endpoint.
*
* @group Events
* @source docs
*/
export interface DocsSearchV2SearchSubmittedEvent {
action: 'docs_search_v2_search_submitted'
properties: {
/**
* The search term sent to the Search V2 endpoint.
*/
query: string
}
}
/**
* User activated a Search V2 result, either by clicking it or selecting it via keyboard.
*
* @group Events
* @source docs
*/
export interface DocsSearchV2ResultClickedEvent {
action: 'docs_search_v2_result_clicked'
properties: {
/**
* The path of the result that was activated.
*/
resultPath: string
/**
* The search term whose results were showing when the result was activated.
*/
query: string
}
}
/**
* User closed the Search V2 dialog.
*
* @group Events
* @source docs
*/
export interface DocsSearchV2ClosedEvent {
action: 'docs_search_v2_closed'
}
/**
* User clicked a recommended page card shown on a docs "not found" page.
*
@@ -4120,6 +4182,10 @@ export type TelemetryEvent =
| AskAiClickedEvent
| DocsAiPromptCopiedEvent
| DocsContentListingClickedEvent
| DocsSearchV2OpenedEvent
| DocsSearchV2SearchSubmittedEvent
| DocsSearchV2ResultClickedEvent
| DocsSearchV2ClosedEvent
| Docs404RecommendationClickedEvent
| DocsProjectConfigVariablesCopyButtonClickedEvent
| HomepageFrameworkQuickstartClickedEvent