Sitemap Configuration
The sitemap is a JSON file that describes your application's structure to the AI. It tells Navieo what routes exist, what interactive elements are on each page, and what user flows are available.
File Location
The CLI generates the sitemap at navieo/sitemap.navieo.json in your project root:
npx navieo init
The generated file looks like this:
{
"appId": "my-app",
"framework": "nextjs",
"generatedAt": "2026-02-15T00:00:00Z",
"routes": [],
"flows": [],
"docs": []
}
Note: The
appIdfield is optional — it's a local label for your reference. Your actual app identity is resolved from your API key when you sync.
Routes
Each route describes a page and the interactive elements on it:
{
"routes": [
{
"path": "/dashboard",
"title": "Dashboard",
"description": "Main dashboard with project list and stats",
"elements": [
{
"id": "create-project",
"type": "button",
"text": "Create Project",
"selector": { "cssSelector": "#create-project" },
"description": "Opens the new project creation dialog"
},
{
"id": "nav-settings",
"type": "link",
"text": "Settings",
"selector": { "cssSelector": "nav a[href='/settings']" },
"description": "Navigation link to the settings page"
}
]
}
]
}
Element Types
| Type | Description |
|---|---|
button | Clickable button element |
link | Navigation link (<a> tag) |
input | Text input field |
select | Dropdown select element |
text | Informational text or section |
Selector Strategies
Each element has a selector object with multiple strategies for finding it in the DOM. The SDK tries them in priority order and uses the first match:
{
"selector": {
"cssSelector": "#create-project",
"navieoId": "create-project",
"ariaLabel": "Create new project",
"text": "Create Project"
}
}
| Field | Maps to | Runtime? | Notes |
|---|---|---|---|
cssSelector | document.querySelector(value) | Yes | Any valid CSS selector |
navieoId | [data-navieo-id="value"] | Yes | Maps to the HTML data-navieo-id attribute |
ariaLabel | [aria-label="value"] | Yes | Maps to the HTML aria-label attribute |
text | — | No | Metadata only — used by the AI for context, not for DOM lookup |
Important: At least one of
cssSelector,navieoId, orariaLabelmust be present for the SDK to find the element at runtime. Thetextfield alone is not sufficient — it's metadata only.
Here are selector strategies ranked by reliability:
| Strategy | Example | Stability |
|---|---|---|
id attribute | "#create-app-button" | Best — unique, survives layout changes |
data-navieo-id | "button[data-navieo-id='save-btn']" | Great — stable if you already use them for testing |
| Semantic selector | "aside a[href='/docs']" | Great — uses meaning, not position |
aria-label | "[aria-label='Create new project']" | Good — accessible and stable |
| Auto-generated heading ID | "#installation" | Good — free if you use a markdown renderer |
| Structural selector | "main > section:nth-of-type(2)" | Fragile — breaks if layout changes |
| Class-based selector | ".bg-blue-600.text-white" | Fragile — breaks with any styling change |
Best practice: Add data-navieo-id or id attributes to key interactive elements in your app. The CLI auto-detects these and generates high-confidence selectors:
<button data-navieo-id="create-project" onClick={handleCreate}>
Create Project
</button>
Route Visibility
You can control which routes are included in sync and where the widget appears using the visibility field on individual routes, or via .navieorc glob patterns:
{
"path": "/admin",
"title": "Admin Panel",
"description": "Internal admin panel",
"elements": [],
"visibility": {
"indexed": false,
"widgetVisible": false
}
}
| Field | Description |
|---|---|
indexed | If false, route is excluded from sync entirely |
widgetVisible | If false, the chat widget is hidden on this route |
You can also set these via the Navieo dashboard or .navieorc patterns.
Flows
Predefined step-by-step flows for common tasks. The AI uses these as templates:
{
"flows": [
{
"name": "create-project",
"description": "How to create a new project",
"steps": [
{
"route": "/dashboard",
"elementId": "create-project-btn",
"action": "highlight"
},
{
"route": "/projects/new",
"elementId": "project-name-input",
"action": "highlight"
}
]
}
]
}
Docs
Contextual documentation that helps the AI understand your application. Place markdown files in navieo/docs/:
navieo/
docs/
getting-started.md
billing.md
team-management.md
The CLI parses these into sections (split on ## headings) during sync. The AI uses this context to answer questions more accurately.
Docs are stored as markdown files — they are not defined inline in the sitemap JSON. The docs field in the sitemap is reserved for internal use.
Generating the Sitemap
Use the Navieo CLI to generate and sync:
# Generate from your codebase
npx navieo init
# Sync to Navieo's backend
NAVIEO_SECRET_KEY=nv_secret_your_key_here npx navieo push
See the CLI Reference for full details.
Tips
- Add
data-navieo-idto key elements — the CLI auto-detects these and gives them high-confidence selectors - Keep selectors up to date — when you rename IDs or change
hrefvalues, runnavieo generateto rescan - Add descriptions — the richer your element descriptions, the better the AI's tour instructions
- Define common flows — predefined flows produce more consistent, higher-quality tours
- Include docs — contextual documentation helps the AI answer "why" questions, not just "how"