Overview
When auto-events is enabled, Trodo automatically captures user interactions without requiring any additional code. This provides comprehensive behavioral data out of the box.
Automatic Events
Event Category Fires When Throttle page_viewnavigation DOM ready Once per load element_clickinteraction Any click None rage_clickinteraction 3+ clicks on same element in 1s 1s detection window dead_clickinteraction Click on non-interactive element, no navigation in 1s 1s post-click delay page_scrollinteraction New max scroll depth reached 250ms debounce text_selectioninteraction ≥3 chars selected, different from last selection 300ms debounce + 1s cooldown element_viewvisibility Element ≥50% visible for ≥1s Once per element per load form_submitform HTML form submits None form_validation_errorform HTML5 invalid event on a field None form_abandonedform Page unloads with form touched but not submitted On beforeunload media_playmedia <video> or <audio> play2s per-element throttle media_pausemedia <video> or <audio> pause2s per-element throttle js_errorerror Runtime JS error or unhandled promise rejection None network_errorerror XHR status ≥400 or network failure None page_performanceperformance ~1500ms after window load Once per load
Declared but not yet firing : element_hover, media_ended, session_start, session_end are in the config map but have no active tracking calls in the current SDK version.
Event Details
page_view
Fires on every page load (DOM ready). In SPAs, also fires on History API navigation (pushState, replaceState) and hash changes.
{
"event_name" : "page_view" ,
"auto_event_data" : {
"page_load_time" : 432 ,
"scroll_position" : 0
}
}
Property Type Description page_load_timenumber ms since navigation start (performance.now()) scroll_positionnumber Always 0 at load time
element_click
Fires on any click. Captures rich coordinates and element context.
{
"event_name" : "element_click" ,
"auto_event_data" : {
"click_coordinates" : { "x" : 540 , "y" : 320 },
"page_x" : 540 ,
"page_y" : 1120 ,
"scroll_x" : 0 ,
"scroll_y" : 800 ,
"document_height" : 4200 ,
"document_width" : 1440 ,
"double_click" : false ,
"element_category" : "button" ,
"element_data" : { ... }
}
}
Property Type Description click_coordinates{x,y}Viewport-relative click position page_x / page_ynumber Page-relative position (viewport + scroll) scroll_x / scroll_ynumber Window scroll at click time document_heightnumber Capped at 25,000px document_widthnumber Capped at 25,000px double_clickboolean true if event.detail === 2element_categorystring "button" | "link" | "form" | "video" | "audio" | "image" | "text" | "other"element_dataobject See Standard Element Data Object
rage_click
Fires when 3 or more clicks occur on the same element within 1 second — a strong signal of user frustration.
{
"event_name" : "rage_click" ,
"auto_event_data" : {
"click_coordinates" : { "x" : 540 , "y" : 320 },
"page_x" : 540 ,
"page_y" : 1120 ,
"scroll_x" : 0 ,
"scroll_y" : 800 ,
"document_height" : 4200 ,
"document_width" : 1440 ,
"click_count" : 5 ,
"time_span" : 820 ,
"element_area" : 3600 ,
"element_category" : "button" ,
"element_data" : { ... }
}
}
Property Type Description click_countnumber Total clicks in the sequence time_spannumber ms between first and last click element_areanumber offsetWidth × offsetHeightelement_categorystring Same as element_click element_dataobject See Standard Element Data Object
dead_click
Fires when a user clicks an element that is not interactive and no navigation occurs within 1 second. Useful for finding broken or confusing UI elements.
{
"event_name" : "dead_click" ,
"auto_event_data" : {
"click_coordinates" : { "x" : 200 , "y" : 450 },
"page_x" : 200 ,
"page_y" : 1250 ,
"scroll_x" : 0 ,
"scroll_y" : 800 ,
"document_height" : 4200 ,
"document_width" : 1440 ,
"element_area" : 1200 ,
"element_category" : "other" ,
"element_has_onclick" : false ,
"element_has_href" : false ,
"element_role" : null ,
"element_data" : { ... }
}
}
Property Type Description element_areanumber offsetWidth × offsetHeightelement_has_onclickboolean Whether the element had an onclick handler element_has_hrefboolean Whether the <a> element had an href element_rolestring | null ARIA role attribute element_dataobject See Standard Element Data Object
page_scroll
Fires whenever the user reaches a new maximum scroll depth on the page. Tracks the highest point scrolled — does not re-fire for upward scrolling.
{
"event_name" : "page_scroll" ,
"auto_event_data" : {
"scroll_depth" : 75 ,
"max_scroll_reached" : 75 ,
"scroll_position" : 2400 ,
"scroll_x" : 0 ,
"scroll_y" : 2400 ,
"document_height" : 3200 ,
"document_width" : 1440
}
}
Property Type Description scroll_depthnumber Current % of page scrolled (0–100) max_scroll_reachednumber Highest % reached this page session scroll_positionnumber window.scrollY in pixelsscroll_x / scroll_ynumber Window scroll values document_heightnumber Full page height in pixels document_widthnumber Full page width in pixels
Fires with a 250ms debounce. Only fires when a new maximum depth is reached, so each percentage is recorded at most once per page load.
text_selection
Fires when the user selects ≥3 characters of text, as long as the selection differs from the previous one. Useful for understanding what content users find important.
{
"event_name" : "text_selection" ,
"auto_event_data" : {
"selected_text" : "Trodo automatically captures..." ,
"selection_length" : 35 ,
"selection_start" : 12 ,
"selection_end" : 47 ,
"anchor_offset" : 12 ,
"focus_offset" : 47 ,
"page_url" : "https://app.example.com/docs" ,
"page_title" : "Getting Started" ,
"page_path" : "/docs" ,
"scroll_x" : 0 ,
"scroll_y" : 400 ,
"document_height" : 3200 ,
"document_width" : 1440 ,
"page_x" : 320 ,
"page_y" : 840 ,
"click_coordinates" : { "x" : 320 , "y" : 440 },
"element_data" : { ... }
}
}
Property Type Description selected_textstring Truncated to 500 characters selection_lengthnumber Full character count of selection selection_start / selection_endnumber | null Range start/end offsets anchor_offset / focus_offsetnumber | null Selection anchor and focus offsets page_x / page_ynumber | null Position of selection on page click_coordinates{x,y} | nullViewport position element_dataobject Containing element of the selection anchor
element_view
Fires when a tracked element becomes at least 50% visible in the viewport for at least 1 second. Requires the element to have an id attribute or data-cq-track attribute.
{
"event_name" : "element_view" ,
"auto_event_data" : {
"time_in_viewport_ms" : 1000 ,
"viewport_percent_visible" : 80 ,
"element_data" : { ... }
}
}
Property Type Description time_in_viewport_msnumber ms from first ≥50% visible to 1s threshold viewport_percent_visiblenumber 0–100, rounded element_dataobject See Standard Element Data Object
To track an element, it must have an id attribute or a data-cq-track attribute. Elements without these are not observed.
Fires when an HTML form is submitted.
{
"event_name" : "form_submit" ,
"auto_event_data" : {
"form_id" : "signup-form" ,
"form_action" : "/api/subscribe" ,
"form_method" : "post" ,
"scroll_x" : 0 ,
"scroll_y" : 600 ,
"document_height" : 3200 ,
"document_width" : 1440 ,
"page_x" : 120 ,
"page_y" : 740 ,
"click_coordinates" : { "x" : 200 , "y" : 140 },
"element_data" : { ... }
}
}
Property Type Description form_idstring | null id attribute of the formform_actionstring | null action attributeform_methodstring "get" or "post"click_coordinates{x,y}Submit button position or form center element_dataobject The form element
Form field values are never captured to protect sensitive data. Use custom events to track specific non-sensitive fields.
Fires on the HTML5 invalid event when a field fails browser-native validation (e.g., required field empty, email format invalid).
{
"event_name" : "form_validation_error" ,
"auto_event_data" : {
"field_id" : "email-field" ,
"field_name" : "email" ,
"field_type" : "email" ,
"form_id" : "signup-form" ,
"validation_message" : "Please include an '@' in the email address." ,
"element_data" : { ... }
}
}
Property Type Description field_idstring Input id attribute (empty string if none) field_namestring Input name attribute field_typestring Input type (e.g. "email") or tag name form_idstring Parent form id (empty string if none) validation_messagestring Browser constraint validation message element_dataobject The input element
Fires via sendBeacon on beforeunload when the user leaves a page with a form they interacted with but did not submit.
{
"event_name" : "form_abandoned" ,
"auto_event_data" : {
"form_id" : "checkout-form" ,
"last_active_field_id" : "card-number" ,
"last_active_field_type" : "text" ,
"fields_filled_count" : 2 ,
"total_fields_count" : 5 ,
"time_on_form_ms" : 34200 ,
"element_data" : { ... }
}
}
Property Type Description form_idstring Form id or "unknown" last_active_field_idstring id of the last interacted fieldlast_active_field_typestring type of the last interacted fieldfields_filled_countnumber Distinct fields with entered values total_fields_countnumber Total form fields time_on_form_msnumber ms from first focus to page unload element_dataobject The form element
form_focus, form_blur, and form_change events are intentionally suppressed — form_abandoned captures the meaningful signal without per-keystroke noise.
Fires when a <video> or <audio> element starts playing. Throttled to once per 2 seconds per element.
{
"event_name" : "media_play" ,
"auto_event_data" : {
"media_type" : "video" ,
"media_src" : "https://cdn.example.com/demo.mp4" ,
"media_duration" : 142.5 ,
"media_current_time" : 0 ,
"scroll_x" : 0 ,
"scroll_y" : 1200 ,
"document_height" : 4000 ,
"document_width" : 1440 ,
"page_x" : 100 ,
"page_y" : 1380 ,
"click_coordinates" : { "x" : 720 , "y" : 180 }
}
}
Property Type Description media_type"video" | "audio"Media element type media_srcstring | null src attributemedia_durationnumber | null Total duration in seconds media_current_timenumber | null Playhead position at time of play click_coordinates{x,y}Center of the element in the viewport
Fires when a <video> or <audio> element is paused. Throttled to once per 2 seconds per element.
{
"event_name" : "media_pause" ,
"auto_event_data" : {
"media_type" : "video" ,
"media_src" : "https://cdn.example.com/demo.mp4" ,
"media_current_time" : 38.2 ,
"media_duration" : 142.5 ,
"scroll_x" : 0 ,
"scroll_y" : 1200 ,
"document_height" : 4000 ,
"document_width" : 1440 ,
"page_x" : 100 ,
"page_y" : 1380 ,
"click_coordinates" : { "x" : 720 , "y" : 180 }
}
}
Same properties as media_play. media_current_time reflects the playhead position at the moment of pause.
js_error
Fires on uncaught JavaScript errors and unhandled promise rejections.
Runtime error (window error event):
{
"event_name" : "js_error" ,
"auto_event_data" : {
"error_type" : "javascript_error" ,
"message" : "Cannot read properties of undefined (reading 'id')" ,
"source" : "https://app.example.com/static/js/main.chunk.js" ,
"line" : 1042 ,
"column" : 18 ,
"stack" : "TypeError: Cannot read properties of undefined... \n at loadUser (main.chunk.js:1042:18)"
}
}
Unhandled promise rejection :
{
"event_name" : "js_error" ,
"auto_event_data" : {
"error_type" : "unhandled_promise_rejection" ,
"message" : "Network request failed" ,
"stack" : "Error: Network request failed \n at fetch..."
}
}
Property Type Description error_typestring "javascript_error" or "unhandled_promise_rejection"messagestring Error message sourcestring Source file URL (runtime errors only) line / columnnumber Error location (runtime errors only) stackstring Stack trace
network_error
Fires when an XHR request returns HTTP status ≥400 or fails entirely. Only SDK-internal requests to sdkapi.trodo.ai are monitored — application XHR is not tracked.
HTTP error (status ≥400):
{
"event_name" : "network_error" ,
"auto_event_data" : {
"url" : "https://sdkapi.trodo.ai/events" ,
"method" : "POST" ,
"status" : 429 ,
"status_text" : "HTTP 429 Error" ,
"duration_ms" : 210
}
}
Network failure (no response):
{
"event_name" : "network_error" ,
"auto_event_data" : {
"url" : "https://sdkapi.trodo.ai/events" ,
"method" : "POST" ,
"status" : 0 ,
"status_text" : "XHR Network Error" ,
"duration_ms" : 5000
}
}
Property Type Description urlstring Request URL methodstring HTTP method ("GET", "POST", etc.) statusnumber HTTP status code, or 0 for network failures status_textstring Human-readable status description duration_msnumber Round-trip time in ms
page_performance
Fires approximately 1500ms after window load, once per page load, with Core Web Vitals and key timing metrics.
{
"event_name" : "page_performance" ,
"auto_event_data" : {
"lcp" : 1820 ,
"cls" : 0.04 ,
"inp" : 140 ,
"fcp" : 980 ,
"ttfb" : 210
}
}
Property Type Description lcpnumber | null Largest Contentful Paint (ms) clsnumber | null Cumulative Layout Shift (0.0–1.0; lower is better) inpnumber | null Interaction to Next Paint (ms) fcpnumber | null First Contentful Paint (ms) ttfbnumber | null Time to First Byte (ms)
Standard Element Data Object
Most interaction events include an element_data sub-object describing the element that was interacted with:
Property Type Description element_tag_namestring | null Lowercase tag name, e.g. "button", "a", "input" element_idstring | null id attributeelement_namestring | null name attribute or data-cq-track valueelement_classstring | null Full className string element_typestring | null type attribute or form methodelement_textstring | null Trimmed textContent, max 100 chars element_categorystring "button" | "link" | "form" | "video" | "audio" | "image" | "text" | "other"element_position{x,y,width,height} | nullViewport coordinates and dimensions
For video element clicks, additional fields:
Property Type Description video_srcstring | null Video src attribute video_durationnumber | null Total duration in seconds video_current_timenumber | null Playhead at time of click
For image element clicks, additional fields:
Property Type Description image_srcstring | null Image src attribute image_altstring | null alt attributeimage_width / image_heightnumber | null Rendered dimensions
Event Envelope
Every auto-event automatically includes these context fields. No additional code is required.
Group Properties Session session_id, user_id, distinct_idPage page_url, page_title, page_path, referrerViewport / Screen viewport_width, viewport_height, screen_width, screen_height, dpiDevice / Browser browser_name, browser_version, os, os_version, device_type, languageGeo country, city, region, timezoneUTM utm_source, utm_medium, utm_campaign, utm_term, utm_content, utm_idProduct context Optional fields your integration adds via track() / people
See Default Properties for the complete list with descriptions.
Configuration
HTML Attribute
Enable auto-events and optionally suppress specific events directly on the script tag:
< script
src = "https://cdn.trodo.ai/scripts/analytics/trodo.script.min.js"
site-id = "YOUR_SITE_ID"
auto-events = "true"
auto-events-disabled-events = "js_error,network_error,page_performance" >
</ script >
Pass a comma-separated list of event names to auto-events-disabled-events.
JS Runtime API
You can also configure auto-events at runtime after the SDK has loaded:
// Disable one or more events
Trodo . disableAutoEvent ([ 'js_error' , 'network_error' ])
// Re-enable a previously disabled event
Trodo . enableAutoEvent ( 'rage_click' )
// Replace the entire disabled list
Trodo . setAutoEventsDisabledEvents ([ 'page_scroll' ])
// Inspect the current configuration
Trodo . getAutoEventsConfig ()
Exclude Paths
Prevent tracking on specific pages:
< script
src = "https://cdn.trodo.ai/scripts/analytics/trodo.script.min.js"
site-id = "YOUR_SITE_ID"
auto-events = "true"
auto-events-disabled-paths = "/admin,/internal,/debug" >
</ script >
Path matching rules:
/admin matches /admin, /admin/users, /admin/settings (prefix match)
Case-sensitive
Multiple paths separated by commas
Disable All Auto-Events
For complete manual control:
< script
src = "https://cdn.trodo.ai/scripts/analytics/trodo.script.min.js"
site-id = "YOUR_SITE_ID"
auto-events = "false" >
</ script >
Storage
Detail Value Table events, with event_type = 'auto'Event payload auto_event_data JSONB columnIndexed element fields element_name, element_id, element_class, element_tag_name, element_type, element_text, element_positionevent_categoryDerived server-side from event_name — not sent by the SDK Normal events Sent via fetch with keepalive: true Unload events (form_abandoned) Sent via navigator.sendBeacon
Best Practices
Recommended Starting Configuration
For most SaaS and agent surfaces, disable the noisiest low-signal events:
< script
src = "https://cdn.trodo.ai/scripts/analytics/trodo.script.min.js"
site-id = "YOUR_SITE_ID"
auto-events = "true"
auto-events-disabled-events = "js_error,network_error,page_performance"
auto-events-disabled-paths = "/admin" >
</ script >
When to Disable Specific Events
Scenario Recommendation High-traffic marketing pages Keep page_view, page_scroll; disable element_click Forms / data-entry apps Disable form_validation_error if noise is high Admin dashboards Exclude path entirely with auto-events-disabled-paths Debugging / internal tools Disable dead_click, rage_click Error monitoring handled elsewhere Disable js_error, network_error
Supplement with Custom Events
Auto-events capture generic interactions. Add custom events for business-specific actions:
// Auto-event captures: element_click on "Run workflow"
// Custom event adds business context:
Trodo . track ( 'agent_run_started' , {
workflow_id: 'weekly_report' ,
surface: 'in_app' ,
model: 'gpt-4o'
});
Next Steps
Track Custom Events Add business-specific events
Default Properties See all auto-captured properties