Requirements control when interactive elements become enabled. They are specified as a requirements array on any interactive, section, guided, multistep, conditional, or quiz block. All requirements in the array must pass for the block to be enabled.
- Requirements: an array of condition strings -- e.g.,
["navmenu-open", "on-page:/dashboard"] - Validation: all requirements must pass for the element to become enabled
- Live checking: event-driven rechecks respond to DOM/navigation changes and relevant clicks; an optional scoped heartbeat can re-validate fragile prerequisites for a short window
- User feedback: failed requirements show helpful explanations with "Fix this" or "Retry" buttons
Purpose: Ensures the navigation menu is open and visible.
{
"type": "interactive",
"action": "highlight",
"reftarget": "a[data-testid='data-testid Nav menu item'][href='/connections']",
"requirements": ["navmenu-open"],
"content": "Click **Connections** in the left-side menu."
}Note: This requirement is auto-fixable -- a "Fix this" button can automatically open the menu. If the user closes the navigation after a fix, the system re-detects the change and reverts the step to the fix state.
Purpose: Verifies the target element specified in reftarget exists on the page.
Note: This requirement is automatically applied by the plugin for all DOM interactions. You don't need to add it manually -- it's included here for reference.
{
"type": "interactive",
"action": "button",
"reftarget": "Save dashboard",
"requirements": ["exists-reftarget"],
"content": "Save your dashboard changes."
}Purpose: Ensures the current form on the page passes validation.
{
"type": "interactive",
"action": "button",
"reftarget": "Save",
"requirements": ["form-valid"],
"content": "Save your configuration."
}Purpose: Ensures the user is on a specific page or URL path.
{
"type": "interactive",
"action": "highlight",
"reftarget": "button[data-testid='add-panel-button']",
"requirements": ["on-page:/dashboard"],
"content": "Add a new panel to your dashboard."
}Examples:
on-page:/dashboard-- any dashboard pageon-page:/connections-- connections pageon-page:/admin-- any admin page
Purpose: Ensures the user is authenticated.
{
"type": "interactive",
"action": "navigate",
"reftarget": "/dashboards",
"requirements": ["is-logged-in"],
"content": "View your dashboards."
}Purpose: Requires the user to have Grafana admin privileges.
{
"type": "interactive",
"action": "navigate",
"reftarget": "/admin/users",
"requirements": ["is-admin"],
"content": "Open the user management page."
}Purpose: Requires the user to have at least Editor role in the current organization.
{
"type": "interactive",
"action": "button",
"reftarget": "Save dashboard",
"requirements": ["is-editor"],
"content": "Save your dashboard changes."
}Purpose: Checks if the user has a specific organizational role.
Supported roles: admin (or grafana-admin), editor, viewer.
{
"type": "interactive",
"action": "button",
"reftarget": "Create dashboard",
"requirements": ["has-role:editor"],
"content": "Create a new dashboard."
}Purpose: Verifies the user has a specific Grafana permission.
{
"type": "interactive",
"action": "navigate",
"reftarget": "/datasources/new",
"requirements": ["has-permission:datasources:create"],
"content": "Create a new data source."
}Purpose: Ensures at least one data source is configured.
{
"type": "interactive",
"action": "navigate",
"reftarget": "/dashboard/new",
"requirements": ["has-datasources"],
"content": "Create your first dashboard."
}Purpose: Checks for a specific data source by name or type (case-insensitive). Searches name first, then type.
Does not test connectivity -- use datasource-configured for that.
{
"type": "interactive",
"action": "formfill",
"reftarget": "textarea[data-testid='query-editor']",
"targetvalue": "rate(http_requests_total[5m])",
"requirements": ["has-datasource:prometheus"],
"content": "Enter a Prometheus query."
}Purpose: Checks that a specific data source exists and passes a connection test. Searches by name or type (case-insensitive), then runs the data source's health check endpoint.
{
"type": "interactive",
"action": "formfill",
"reftarget": "textarea[data-testid='query-editor']",
"targetvalue": "{job=\"grafana\"}",
"requirements": ["datasource-configured:loki"],
"content": "Enter a Loki query."
}Difference from has-datasource:
| Requirement | Checks existence | Checks connectivity |
|---|---|---|
has-datasource:X |
Yes | No |
datasource-configured:X |
Yes | Yes |
Purpose: Verifies a specific plugin is installed (may be disabled).
{
"type": "interactive",
"action": "navigate",
"reftarget": "/a/volkovlabs-rss-datasource",
"requirements": ["has-plugin:volkovlabs-rss-datasource"],
"content": "Configure the RSS data source plugin."
}Purpose: Verifies a specific plugin is installed and enabled (ready to use).
{
"type": "interactive",
"action": "navigate",
"reftarget": "/a/volkovlabs-rss-datasource",
"requirements": ["plugin-enabled:volkovlabs-rss-datasource"],
"content": "Open the RSS data source plugin."
}Difference from has-plugin:
| Requirement | Checks installed | Checks enabled |
|---|---|---|
has-plugin:X |
Yes | No |
plugin-enabled:X |
Yes | Yes |
Purpose: Ensures at least one dashboard exists in the current organization.
{
"type": "interactive",
"action": "navigate",
"reftarget": "/dashboards",
"requirements": ["dashboard-exists"],
"content": "View your existing dashboards."
}Purpose: Ensures a dashboard with a specific title exists (case-insensitive).
{
"type": "interactive",
"action": "navigate",
"reftarget": "/d/monitoring-overview",
"requirements": ["has-dashboard-named:System Monitoring"],
"content": "Open your monitoring dashboard."
}Purpose: Checks if a Grafana feature toggle is enabled.
{
"type": "interactive",
"action": "button",
"reftarget": "Query splitting",
"requirements": ["has-feature:queryLibrary"],
"content": "Use the query library feature."
}Purpose: Restricts functionality to specific Grafana environments.
Values: development, production, cloud.
{
"type": "interactive",
"action": "navigate",
"reftarget": "/admin/settings",
"requirements": ["in-environment:development"],
"content": "Access development settings."
}Purpose: Ensures Grafana version meets a minimum semver requirement.
{
"type": "interactive",
"action": "button",
"reftarget": "Scene app",
"requirements": ["min-version:9.0.0"],
"content": "Open the new scene-based application."
}Purpose: Controls content visibility based on the rendering context. Used for context-aware content that should differ between the Pathfinder app and other rendering environments (e.g., a public documentation website).
Supported values:
| Value | In Pathfinder app | Description |
|---|---|---|
pathfinder |
Always true |
Content is shown in the Pathfinder app |
website |
Always false |
Content is only for website/public docs context |
{
"type": "conditional",
"conditions": ["renderer:pathfinder"],
"whenTrue": [{ "type": "markdown", "content": "Click **Show me** below to highlight the button in the Grafana UI." }],
"whenFalse": [{ "type": "markdown", "content": "Navigate to the Connections page in your Grafana instance." }]
}This requirement is evaluated differently by different rendering tools, allowing the same guide source to produce different content in different contexts.
Purpose: Verifies that a Coda terminal session is connected and active. Use this requirement on terminal blocks to ensure the user has an active terminal before attempting to execute commands.
{
"type": "terminal",
"command": "curl -s http://localhost:9090/api/v1/status/config | jq .",
"requirements": ["is-terminal-active"],
"content": "Check the Prometheus configuration."
}Note: Place a terminal-connect block before any terminal blocks to give users a way to establish the connection.
Purpose: Checks if a guide response variable has a specific value. Variables are set by input blocks.
{
"type": "section",
"title": "Advanced configuration",
"requirements": ["var-termsAccepted:true"],
"blocks": []
}Syntax: var-{variableName}:{expectedValue}
Examples:
var-termsAccepted:true-- boolean variable must betruevar-experienceLevel:advanced-- text variable must equal"advanced"var-datasourceName:prometheus-- variable must match specific valuevar-datasourceName:*-- wildcard, passes if variable has any non-empty value
Used with conditional blocks:
{
"type": "conditional",
"conditions": ["var-isProd:true"],
"whenTrue": [{ "type": "markdown", "content": "Production settings enabled." }],
"whenFalse": [{ "type": "markdown", "content": "Development mode active." }]
}See variable substitution for more details.
Purpose: Creates dependencies between sections, ensuring prerequisite sections are completed first.
{
"type": "section",
"id": "create-dashboard",
"title": "Create a dashboard",
"requirements": ["section-completed:setup-datasource"],
"blocks": []
}All requirements in the array must pass. Use multiple entries for AND logic.
{
"type": "interactive",
"action": "button",
"reftarget": "Delete user",
"requirements": ["is-admin", "on-page:/admin/users"],
"content": "Remove the selected user."
}Note:
exists-reftargetis automatically applied to all DOM actions, so it doesn't need to be included in these combinations.
Navigation actions:
"requirements": ["navmenu-open"]Admin actions:
"requirements": ["is-admin", "on-page:/admin"]Data source actions:
"requirements": ["has-datasource:prometheus", "on-page:/explore"]Objectives declare what a guide step will accomplish. They use the same syntax as requirements but serve a different purpose.
- Auto-completion: if an objective is already met when a user visits a guide, the step is automatically marked complete with an "Already done!" message
- Skip unnecessary work: users do not need to redo steps they have already accomplished
{
"type": "interactive",
"action": "button",
"reftarget": "Install plugin",
"requirements": ["exists-reftarget"],
"objectives": ["has-plugin:volkovlabs-rss-datasource"],
"content": "Install the RSS data source plugin."
}- Objectives always win: if objectives are met, the step is marked complete regardless of requirements state
- All-or-nothing: when multiple objectives are specified, ALL must be met
- Same syntax as requirements: use any requirement type as an objective
| Aspect | Requirements | Objectives |
|---|---|---|
| Purpose | Gate when step CAN execute | Gate WHETHER step NEEDS to execute |
| When met | Step becomes enabled | Step is auto-completed |
| Empty/missing | Always allowed to execute | Must be manually completed |
- Maximum 10 components per condition string (comma-separated)
- Fixed types (
is-admin,is-logged-in,is-editor,exists-reftarget(auto-applied),navmenu-open,has-datasources,dashboard-exists,form-valid,is-terminal-active) cannot have arguments - Parameterized types (
has-datasource:X,on-page:/path,var-name:value) require an argument after the colon - Path arguments (e.g.,
on-page:) should start with/ - Version arguments (e.g.,
min-version:) should be semver format (e.g.,11.0.0) - Variable arguments (e.g.,
var-) use formatvar-{variableName}:{expectedValue}
| Invalid | Error | Fix |
|---|---|---|
is-admin:true |
Unexpected argument | is-admin |
has-datasource: |
Missing argument | has-datasource:prometheus |
has-datasource |
Unknown type | has-datasource:X or has-datasources |
on-page:dashboard |
Invalid path format | on-page:/dashboard |
min-version:latest |
Invalid version format | min-version:11.0.0 |
var-myVar |
Missing value | var-myVar:true |
var-:value |
Missing variable name | var-variableName:value |
| Requirement | Purpose |
|---|---|
navmenu-open |
Navigation menu is open and visible |
exists-reftarget |
Target element exists on the page |
form-valid |
Current form passes validation |
is-logged-in |
User is authenticated |
is-admin |
User has Grafana admin privileges |
is-editor |
User has at least Editor role |
has-datasources |
At least one data source is configured |
dashboard-exists |
At least one dashboard exists |
is-terminal-active |
Coda terminal session is connected |
| Requirement | Purpose |
|---|---|
on-page:<path> |
User is on a specific page |
has-role:<role> |
User has a specific organizational role |
has-permission:<permission> |
User has a specific Grafana permission |
has-datasource:<identifier> |
Specific data source exists (by name or type) |
datasource-configured:<identifier> |
Specific data source exists and passes connection test |
has-plugin:<pluginId> |
Specific plugin is installed |
plugin-enabled:<pluginId> |
Specific plugin is installed and enabled |
has-dashboard-named:<title> |
Dashboard with specific title exists |
has-feature:<toggle> |
Feature toggle is enabled |
in-environment:<env> |
Running in a specific environment |
min-version:<version> |
Grafana version meets minimum requirement |
section-completed:<sectionId> |
Another section has been completed |
var-<name>:<value> |
Guide variable has expected value (* = any non-empty) |
renderer:<renderer> |
Rendering context matches (pathfinder or website) |
Each requirement provides helpful error messages and, where possible, "Fix this" buttons:
- Automatic fixes:
navmenu-opencan auto-open the navigation - Retry buttons: most requirements offer retry functionality
- Clear explanations: users understand what needs to be done
- Contextual help: error messages explain why the requirement exists
Requirements never pass:
- Check browser console for detailed error messages
- Verify requirement syntax matches examples exactly
- Ensure required elements/data actually exist
Requirements pass but should not:
- Requirements may be cached -- try refreshing the page
- Check for typos in requirement names
- Verify case sensitivity for names and identifiers
"Fix this" button does not work:
- Only certain requirements support automatic fixing
- Check browser console for error details
- Some fixes require specific user permissions
Enable development mode logging:
localStorage.setItem('grafana-docs-debug', 'true');
// Reload page to see detailed requirement checking logs- JSON Guide Reference - Block types, properties, and guide structure
- Interactive Actions - Action type behavior
- Selectors Reference - Stable selector patterns