Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Instrument and discover analytics events in Sentry's frontend UI. Use when adding tracking to buttons, pages, modals, or custom interactions, when defining new analytics events, when searching for existing events, when auditing analytics coverage for a feature, or when answering questions about how users interact with a feature. Trigger on "add analytics", "track event", "instrument analytics", "analytics event", "track click", "track page view", "add tracking", "what events exist for", "audit a
.claude/skills/getsentry-analytics/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-15 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 63% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 108% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 37% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 1% | 0% |
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).bashgrep -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.trackAnalytics() calls must be type-safe. Every event key passed to trackAnalytics() must exist in a *EventParameters type and be registered in the domain's event map. This enforces that organization is always passed and that call sites sharing the same event key use consistent parameters. Declarative helpers — button analyticsEventKey/analyticsParams props and useRouteAnalyticsParams — are exempt because each instance is a one-off: two buttons labeled "Save" are inherently different (different forms, different contexts), so there are no shared call sites and less value in centralized types.trackAnalytics() only for interactions those helpers don't cover.trackAnalytics() or built-in helpers. Never call window.analytics, Amplitude.track(), or any other analytics SDK directly.organization to trackAnalytics — the override system handles the rest.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-08 | pass→fail | 9,232 | 4,788 | -48% | 1 | 1 | 0% | 1,716 | 2,134 | +24% | 0 | 0 | — |
case-15 | fail→pass | 9,168 | 1,869 | -80% | 1 | 1 | 0% | 1,547 | 2,190 | +42% | 0 | 0 | — |
case-01 | fail→fail | 5,371 | 4,582 | -15% | 1 | 1 | 0% | 912 | 2,146 | +135% | 0 | 0 | — |
case-02 | fail→fail | 4,125 | 5,376 | +30% | 1 | 1 | 0% | 272 | 2,208 | +712% | 0 | 0 | — |
case-03 | fail→fail | 7,379 | 4,723 | -36% | 1 | 1 | 0% | 1,449 | 2,152 | +49% | 0 | 0 | — |
case-09 | pass→fail | 6,520 | 6,763 | +4% | 1 | 1 | 0% | 1,149 | 2,346 | +104% | 0 | 0 | — |
case-04 | pass→pass | 5,479 | 6,727 | +23% | 1 | 1 | 0% | 1,135 | 3,179 | +180% | 0 | 0 | — |
case-05 | pass→pass | 12,944 | 11,096 | -14% | 1 | 1 | 0% | 2,312 | 3,893 | +68% | 0 | 0 | — |
case-06 | pass→fail | 11,413 | 12,001 | +5% | 1 | 1 | 0% | 2,299 | 3,693 | +61% | 0 | 0 | — |
case-07 | pass→pass | 6,853 | 3,102 | -55% | 1 | 1 | 0% | 1,257 | 2,497 | +99% | 0 | 0 | — |
case-10 | pass→pass | 10,205 | 3,640 | -64% | 1 | 1 | 0% | 2,033 | 2,600 | +28% | 0 | 0 | — |
case-11 | fail→fail | 4,450 | 4,937 | +11% | 1 | 1 | 0% | 187 | 2,170 | +1060% | 0 | 0 | — |
case-12 | fail→pass | 8,155 | 3,913 | -52% | 1 | 1 | 0% | 1,601 | 2,603 | +63% | 0 | 0 | — |
case-13 | pass→pass | 6,555 | 1,358 | -79% | 1 | 1 | 0% | 1,104 | 2,101 | +90% | 0 | 0 | — |
case-14 | fail→pass | 6,789 | 3,026 | -55% | 1 | 1 | 0% | 1,200 | 2,501 | +108% | 0 | 0 | — |
case-16 | fail→pass | 12,237 | 3,936 | -68% | 1 | 1 | 0% | 1,923 | 2,637 | +37% | 0 | 0 | — |
case-17 | pass→pass | 9,287 | 6,876 | -26% | 1 | 1 | 0% | 1,563 | 2,829 | +81% | 0 | 0 | — |
case-18 | fail→pass | 12,325 | 2,582 | -79% | 1 | 1 | 0% | 2,345 | 2,362 | +1% | 0 | 0 | — |
case-19 | fail→pass | 9,969 | 1,628 | -84% | 1 | 1 | 0% | 1,615 | 2,112 | +31% | 0 | 0 | — |
case-20 | pass→pass | 7,769 | 3,054 | -61% | 1 | 1 | 0% | 1,443 | 2,087 | +45% | 0 | 0 | — |
case-21 | fail→pass | 9,505 | 3,358 | -65% | 1 | 1 | 0% | 1,547 | 2,489 | +61% | 0 | 0 | — |
case-22 | pass→pass | 12,661 | 1,783 | -86% | 1 | 1 | 0% | 2,400 | 2,112 | -12% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 16 counted toward the lift figure. The other 6 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +18 percentage points is the difference between those two pass rates over the 16 comparable cases. 4 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.