Learn how NAVAI enables voice-controlled navigation through route definitions, resolution, and the navigate_to tool
NAVAI allows users to navigate your application using natural voice commands. The AI agent understands route names, paths, and synonyms to provide intuitive voice-first navigation.
The resolveNavaiRoute function tries multiple matching strategies in order:
// From packages/voice-frontend/src/routes.ts:16-33export function resolveNavaiRoute(input: string, routes: NavaiRoute[] = []): string | null { const normalized = normalize(input); // 1. Direct path match const direct = routes.find((route) => normalize(route.path) === normalized); if (direct) return direct.path; // 2. Exact name or synonym match for (const route of routes) { if (normalize(route.name) === normalized) return route.path; if (route.synonyms?.some((synonym) => normalize(synonym) === normalized)) return route.path; } // 3. Partial name or synonym match for (const route of routes) { if (normalized.includes(normalize(route.name))) return route.path; if (route.synonyms?.some((synonym) => normalized.includes(normalize(synonym)))) return route.path; } return null;}
When building the agent, NAVAI generates instructions that teach the AI about available routes:
// From packages/voice-frontend/src/agent.ts:217-243const routeLines = getNavaiRoutePromptLines(options.routes);const instructions = [ options.baseInstructions ?? "You are a voice assistant embedded in a web app.", "Allowed routes:", ...routeLines, "Allowed app functions:", ...functionLines, "Rules:", "- If user asks to go/open a section, always call navigate_to.", "- If user asks to run an internal action, call execute_app_function or the matching direct function tool.", "- Always include payload in execute_app_function. Use null when no arguments are needed.", "- For execute_app_function, pass arguments using payload.args (array).", "- For class methods, pass payload.constructorArgs and payload.methodArgs.", "- Never invent routes or function names that are not listed.", "- If destination/action is unclear, ask a brief clarifying question."].join("\n");
- home (/) aliases: dashboard, main, start- profile (/profile) aliases: account, my profile, user info- settings (/settings) aliases: preferences, config- messages (/messages) aliases: inbox, chat, conversations
The AI uses these instructions to understand which routes are available and what they’re called. Clear, descriptive route names help the AI make better navigation decisions.
Instead of defining parametrized routes, create functions that navigate with parameters:
// Define a function instead of a routeexport function openUserProfile(userId: string, context: NavaiFunctionContext) { context.navigate(`/users/${userId}`); return { ok: true, message: `Opening profile for user ${userId}` };}// Register this function with NAVAI// User can say: "Open user profile 12345"// AI calls: openUserProfile("12345")
For large apps, only expose the most commonly needed routes to voice navigation. Not every page needs to be voice-accessible.
Test with real commands
Test your routes with natural voice commands to ensure they resolve correctly:
import { resolveNavaiRoute } from '@navai/voice-frontend';console.log(resolveNavaiRoute("show me settings", routes));console.log(resolveNavaiRoute("go to my account", routes));