.agents/skills/analytics/SKILL.md
Add analytics events to Sentry's frontend UI using established patterns.
When the user asks about usage, adoption, or interaction counts for a feature:
AskUserQuestion to ask whether they want to instrument it. Do not proceed to instrumentation without explicit confirmation.Read references/amplitude-mcp.md for the full discovery and querying workflow.
NEVER create a new event without checking if one already exists.
static/app/utils/analytics/ for events matching the feature domain.clicked, viewed, created).grep -rn "keyword" static/app/utils/analytics/ --include="*.tsx"
| Rule | Example |
|---|---|
Use snake_case with dots as separators | feedback.list-item-selected |
| First segment = feature domain | dashboards2., issue_details., feedback. |
| Middle segments = section/context (optional) | dashboards2.edit. |
| Last segment = action | .clicked, .viewed, .created, .changed |
| Match the existing domain file's prefix | If events are in feedbackAnalyticsEvents.tsx, use feedback. prefix |
Standard action suffixes:
| User action | Suffix |
|---|---|
| Clicks a button/link | .clicked or _clicked |
| Views a page | .viewed |
| Submits a form | .submitted or .created |
| Changes a setting | .changed |
| Renders/loads content | .rendered or .loaded |
| Dismisses UI | .dismissed |
| Opens a modal/panel | .opened |
| What to track | Pattern | Open reference |
|---|---|---|
| Page view on route navigation | Route analytics hooks | references/tracking-patterns.md § Route-Level |
| Button or link click | Button analyticsEventKey prop | references/tracking-patterns.md § Button |
| Custom interaction (toggle, drag, select) | trackAnalytics() call | references/tracking-patterns.md § Manual |
| Modal or panel open/close | trackAnalytics() in handler | references/tracking-patterns.md § Manual |
| UI area context for events | AnalyticsArea wrapper | references/tracking-patterns.md § Area Context |
Read references/event-definitions.md for step-by-step instructions.
Read references/troubleshooting.md when:
trackAnalytics| File | Purpose |
|---|---|
static/app/utils/analytics.tsx | Master registry — all event maps merged, trackAnalytics export |
static/app/utils/analytics/{domain}AnalyticsEvents.tsx | Domain-specific event type definitions and name maps |
static/app/utils/analytics/makeAnalyticsFunction.tsx | Factory that creates typed trackAnalytics — do not call directly |
static/app/utils/routeAnalytics/useRouteAnalyticsEventNames.tsx | Hook for route-level page view event names |
static/app/utils/routeAnalytics/useRouteAnalyticsParams.tsx | Hook for route-level page view parameters |
static/app/components/analyticsArea.tsx | AnalyticsArea component and useAnalyticsArea hook |
static/app/components/core/button/types.tsx | Button analytics props (analyticsEventKey, analyticsEventName, analyticsParams) |
Users of this skill may be less technical. Use AskUserQuestion at every decision point instead of dumping plans or code.
| Situation | Action |
|---|---|
| Event not found, user asked a data question | Use AskUserQuestion: "This isn't tracked yet. Want me to add instrumentation?" |
| User confirms they want instrumentation | Go straight to implementation. Do not show code previews or step-by-step plans — just make the changes and summarize what you did. |
| Implementation is done, needs user action (e.g., Reload registration) | State the remaining step clearly in your summary. |
Never dump code blocks as a "plan" and then ask "Want me to make these changes?" — either present a short plain-English summary via AskUserQuestion for confirmation, or proceed directly if the user already asked for instrumentation.
Every trackAnalytics call flows through the GetSentry override in static/gsApp/utils/rawTrackAnalyticsEvent.tsx:
| Destination | When it fires | What it uses | How to query |
|---|---|---|---|
| Reload | Always | eventKey | Redash |
| Amplitude | When eventName is non-null and org exists | eventName | Amplitude UI or MCP |
| Pendo | Same as Amplitude | eventName | Pendo |
eventName to a string (e.g., 'Logs Trace Link Clicked') to send to both Reload and Amplitude. This is the default for almost all events.eventName to null only for high-volume events that would be too expensive for Amplitude. These are Reload-only and queryable via Redash.allow_no_schema: true — no separate registration step is needed.null name) will not appear in Amplitude search. Fall back to grepping the codebase if Amplitude returns no results.*EventParameters type and be registered in the domain's event map.trackAnalytics(). Never call window.analytics, Amplitude.track(), or any other analytics SDK directly.organization to trackAnalytics — the override system handles the rest.