Skip to main content

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

EventCategoryFires WhenThrottle
page_viewnavigationDOM readyOnce per load
element_clickinteractionAny clickNone
rage_clickinteraction3+ clicks on same element in 1s1s detection window
dead_clickinteractionClick on non-interactive element, no navigation in 1s1s post-click delay
page_scrollinteractionNew max scroll depth reached250ms debounce
text_selectioninteraction≥3 chars selected, different from last selection300ms debounce + 1s cooldown
element_viewvisibilityElement ≥50% visible for ≥1sOnce per element per load
form_submitformHTML form submitsNone
form_validation_errorformHTML5 invalid event on a fieldNone
form_abandonedformPage unloads with form touched but not submittedOn beforeunload
media_playmedia<video> or <audio> play2s per-element throttle
media_pausemedia<video> or <audio> pause2s per-element throttle
js_errorerrorRuntime JS error or unhandled promise rejectionNone
network_errorerrorXHR status ≥400 or network failureNone
page_performanceperformance~1500ms after window loadOnce 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
  }
}
PropertyTypeDescription
page_load_timenumberms since navigation start (performance.now())
scroll_positionnumberAlways 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": { ... }
  }
}
PropertyTypeDescription
click_coordinates{x,y}Viewport-relative click position
page_x / page_ynumberPage-relative position (viewport + scroll)
scroll_x / scroll_ynumberWindow scroll at click time
document_heightnumberCapped at 25,000px
document_widthnumberCapped at 25,000px
double_clickbooleantrue if event.detail === 2
element_categorystring"button" | "link" | "form" | "video" | "audio" | "image" | "text" | "other"
element_dataobjectSee 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": { ... }
  }
}
PropertyTypeDescription
click_countnumberTotal clicks in the sequence
time_spannumberms between first and last click
element_areanumberoffsetWidth × offsetHeight
element_categorystringSame as element_click
element_dataobjectSee 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": { ... }
  }
}
PropertyTypeDescription
element_areanumberoffsetWidth × offsetHeight
element_has_onclickbooleanWhether the element had an onclick handler
element_has_hrefbooleanWhether the <a> element had an href
element_rolestring | nullARIA role attribute
element_dataobjectSee 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
  }
}
PropertyTypeDescription
scroll_depthnumberCurrent % of page scrolled (0–100)
max_scroll_reachednumberHighest % reached this page session
scroll_positionnumberwindow.scrollY in pixels
scroll_x / scroll_ynumberWindow scroll values
document_heightnumberFull page height in pixels
document_widthnumberFull 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": { ... }
  }
}
PropertyTypeDescription
selected_textstringTruncated to 500 characters
selection_lengthnumberFull character count of selection
selection_start / selection_endnumber | nullRange start/end offsets
anchor_offset / focus_offsetnumber | nullSelection anchor and focus offsets
page_x / page_ynumber | nullPosition of selection on page
click_coordinates{x,y} | nullViewport position
element_dataobjectContaining 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": { ... }
  }
}
PropertyTypeDescription
time_in_viewport_msnumberms from first ≥50% visible to 1s threshold
viewport_percent_visiblenumber0–100, rounded
element_dataobjectSee 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.

form_submit

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": { ... }
  }
}
PropertyTypeDescription
form_idstring | nullid attribute of the form
form_actionstring | nullaction attribute
form_methodstring"get" or "post"
click_coordinates{x,y}Submit button position or form center
element_dataobjectThe form element
Form field values are never captured to protect sensitive data. Use custom events to track specific non-sensitive fields.

form_validation_error

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": { ... }
  }
}
PropertyTypeDescription
field_idstringInput id attribute (empty string if none)
field_namestringInput name attribute
field_typestringInput type (e.g. "email") or tag name
form_idstringParent form id (empty string if none)
validation_messagestringBrowser constraint validation message
element_dataobjectThe input element

form_abandoned

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": { ... }
  }
}
PropertyTypeDescription
form_idstringForm id or "unknown"
last_active_field_idstringid of the last interacted field
last_active_field_typestringtype of the last interacted field
fields_filled_countnumberDistinct fields with entered values
total_fields_countnumberTotal form fields
time_on_form_msnumberms from first focus to page unload
element_dataobjectThe form element
form_focus, form_blur, and form_change events are intentionally suppressed — form_abandoned captures the meaningful signal without per-keystroke noise.

media_play

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 }
  }
}
PropertyTypeDescription
media_type"video" | "audio"Media element type
media_srcstring | nullsrc attribute
media_durationnumber | nullTotal duration in seconds
media_current_timenumber | nullPlayhead position at time of play
click_coordinates{x,y}Center of the element in the viewport

media_pause

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..."
  }
}
PropertyTypeDescription
error_typestring"javascript_error" or "unhandled_promise_rejection"
messagestringError message
sourcestringSource file URL (runtime errors only)
line / columnnumberError location (runtime errors only)
stackstringStack 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
  }
}
PropertyTypeDescription
urlstringRequest URL
methodstringHTTP method ("GET", "POST", etc.)
statusnumberHTTP status code, or 0 for network failures
status_textstringHuman-readable status description
duration_msnumberRound-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
  }
}
PropertyTypeDescription
lcpnumber | nullLargest Contentful Paint (ms)
clsnumber | nullCumulative Layout Shift (0.0–1.0; lower is better)
inpnumber | nullInteraction to Next Paint (ms)
fcpnumber | nullFirst Contentful Paint (ms)
ttfbnumber | nullTime to First Byte (ms)

Standard Element Data Object

Most interaction events include an element_data sub-object describing the element that was interacted with:
PropertyTypeDescription
element_tag_namestring | nullLowercase tag name, e.g. "button", "a", "input"
element_idstring | nullid attribute
element_namestring | nullname attribute or data-cq-track value
element_classstring | nullFull className string
element_typestring | nulltype attribute or form method
element_textstring | nullTrimmed 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:
PropertyTypeDescription
video_srcstring | nullVideo src attribute
video_durationnumber | nullTotal duration in seconds
video_current_timenumber | nullPlayhead at time of click
For image element clicks, additional fields:
PropertyTypeDescription
image_srcstring | nullImage src attribute
image_altstring | nullalt attribute
image_width / image_heightnumber | nullRendered dimensions

Event Envelope

Every auto-event automatically includes these context fields. No additional code is required.
GroupProperties
Sessionsession_id, user_id, distinct_id
Pagepage_url, page_title, page_path, referrer
Viewport / Screenviewport_width, viewport_height, screen_width, screen_height, dpi
Device / Browserbrowser_name, browser_version, os, os_version, device_type, language
Geocountry, city, region, timezone
UTMutm_source, utm_medium, utm_campaign, utm_term, utm_content, utm_id
Product contextOptional 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

DetailValue
Tableevents, with event_type = 'auto'
Event payloadauto_event_data JSONB column
Indexed element fieldselement_name, element_id, element_class, element_tag_name, element_type, element_text, element_position
event_categoryDerived server-side from event_name — not sent by the SDK
Normal eventsSent via fetch with keepalive: true
Unload events (form_abandoned)Sent via navigator.sendBeacon

Best Practices

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

ScenarioRecommendation
High-traffic marketing pagesKeep page_view, page_scroll; disable element_click
Forms / data-entry appsDisable form_validation_error if noise is high
Admin dashboardsExclude path entirely with auto-events-disabled-paths
Debugging / internal toolsDisable dead_click, rage_click
Error monitoring handled elsewhereDisable 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