Interactive learning architecture
Interactive learning is an app plugin built on the Grafana plugin SDK. Its primary mount point is the Grafana extension sidebar — the same surface used by Grafana Assistant — which lets the plugin operate alongside any part of the Grafana UI.
The plugin is composed of a React + TypeScript frontend and a Go backend. The frontend handles all UI, recommendation rendering, and step execution; the backend handles network proxying, custom-guide storage, and (optionally) sandbox VM and terminal session management.
High-level subsystems
Interactive learning has six subsystems that work together:

Context engine
The context engine continuously observes Grafana state and produces a ContextData object. The following table outlines the data points it collects.
Hashing of user_id and user_email happens client-side before the request leaves the browser. The plugin never sends raw user identifiers to the recommender.
Recommendation pipeline
The recommendation pipeline produces the cards you see in the docs panel. It uses a multi-source strategy:
- Recommender service — A REST API hosted by Grafana Labs that pattern-matches on the context object and returns recommendations.
- Bundled guides — Guides packaged into the plugin bundle (in
src/bundled-interactives/). Used as a fallback when the recommender is unreachable, and also for guides that should always be available. - Custom guides — Guides published by editors and admins through the block editor, stored in the Pathfinder backend.
- Package resolver — A composite resolver that turns recommendations into renderable guides by fetching each one from its canonical source (CDN, bundled, or backend) and applying any local user state.
The recommender service URL auto-selects based on the Grafana instance hostname (production, ops, or development) — administrators can override this in plugin settings if needed. The recommender service is disabled by default for OSS Grafana instances; admins can enable it from the plugin configuration page.
Note
The recommender service is enabled by default on Grafana Cloud. On OSS, an administrator must enable it under Plugin configuration > Recommendations. For more information, refer to the Administrators reference.
Documentation renderer
Pathfinder fetches guide content as JSON and renders it through a React component tree — never an iframe. This lets the rendered guide use the same Grafana theme, components, and styles as the rest of the UI, and it makes images, videos, code blocks, and interactive controls feel native.
The renderer is block-based — every guide is a list of typed blocks (markdown, image, video, section, conditional, interactive, multistep, guided, quiz, input, code-block, grot-guide, and others). Each block type maps to a specific React component. Variable substitution ({{variableName}}) and conditional branches (has-datasource:prometheus, is-admin, var-policyAccepted:true) are evaluated at render time, so the same guide can render different content for different users.
Long guides use progressive scroll discovery: blocks reveal themselves and re-resolve their selectors as the reader scrolls into them, so a guide can target elements inside virtualized containers (for example, long dashboard lists) without having to keep them all mounted.
Interactive engine
The interactive engine powers the Show me and Do it buttons inside guides. It supports several action types:
Steps can be grouped into:
- Sections — A linear sequence with a single Do section button.
- Multistep blocks — A sequence that runs all actions automatically when Do it is clicked.
- Guided blocks — A sequence the user performs themselves; the engine highlights each step and waits for the user to act.
- Conditional blocks — Two branches of content rendered based on a runtime condition (data source presence, user role, variable values).
Each step can declare requirements that must be met before it can run — for example navmenu-open, is-admin, has-datasource:prometheus, or on-page:/dashboards. The requirements manager checks them, and where it can, offers a Fix button that performs the prerequisite for the user.
Selector resilience
Targeting elements in a constantly-evolving UI like Grafana is hard, so the interactive engine ships with a selector resilience pipeline that escalates strategies until it finds a match:
- Native CSS —
querySelectoragainst the user-provided selector. - Enhanced selectors —
:contains(),:has(),:nth-match(), and the custompanel:domain prefix. :text()exact match — for short button labels (under 20 characters), eliminating false positives that substring matches would produce.data-testidprefix matching — when the exact ID isn’t found but a unique prefix exists.- Retry with backoff — exponential backoff (200 ms / 600 ms / 1.8 s) gives lazy-loaded UI time to mount.
Each resolution also returns a confidence score that the block editor surfaces as a Selector Health badge (green / yellow / red), so guide authors can spot fragile selectors before publishing.
Block editor and custom guides
The block editor lets editors and admins compose guides without writing any JSON. Guides flow through three states:
The backend stores guides as InteractiveGuide custom resources in the pathfinderbackend.ext.grafana.com/v1alpha1 API group. The backend is shipped as part of the plugin’s Go server — there is no external service to deploy. Custom guides are scoped to the Grafana stack they are published on; they are not shared between stacks.
The block editor can also import and export the underlying JSON, which is useful for bringing a guide from a development stack to production, or for review through a GitHub pull request.
The floating panel
The Pathfinder docs panel can render in two modes:
- Docked — the default; lives in the Grafana extension sidebar.
- Floating — a free-floating, resizable, draggable window that you can position anywhere on screen and minimize to a small pill.
Switching modes is a user action (the Pop out button at the top of the panel) but can also be driven by a guide step (the popout action). Geometry, minimized state, and dock target are persisted per-instance, so the panel returns to where you last left it.
Tracking user progress
Pathfinder uses two storage tiers for progress:
- localStorage for unauthenticated state — open tabs, in-flight progress, last-visited milestone, custom-guide drafts in progress, recently-used VM options.
- Grafana user-storage (server-side) for state that needs to follow the user across browsers — completed milestones, badges, streaks, and per-instance auto-open flags.
State that lives in both is reconciled by timestamp on read — the most recent value wins. This means progress made in one browser shows up in another after a refresh.
Tabs and the per-tab guide progression persist across sessions until the user explicitly closes a tab.
Live sessions (experimental)
Live sessions enable a presenter to broadcast their Show me and Do it actions to attendees over a peer-to-peer WebRTC connection. The plugin uses a small PeerJS signalling server to bootstrap the connection; once peers are connected, all guide data flows directly between browsers without round-tripping through any server. Presenters authenticate with an ECDSA P-256 key pair to prevent peer ID impersonation on the signalling layer.
Coda terminal (optional)
When enabled, Coda gives a guide direct access to a 30-minute sandbox VM through a terminal panel inside the docs panel. The plugin’s Go backend handles VM provisioning, SSH key management, and the WebSocket-to-SSH relay; the frontend never sees the credentials. Guide authors can drop a terminal-connect block into a guide to provision a specific VM template (generic Linux, sample-app, or Alloy scenario) and a terminal block to run commands in the resulting session.


