Route Definition
Routes define the navigable destinations in your application that can be accessed via voice commands.
NavaiRoute Type
type NavaiRoute = {
name: string;
path: string;
description: string;
synonyms?: string[];
};
Route Fields
Primary name for the route. Used for matching voice input.
URL path to navigate to when route is resolved.
Human-readable description. Included in the agent’s prompt to help understand the route’s purpose.description: 'User profile page with account settings'
Alternative names or translations. Useful for multilingual apps.synonyms: ['perfil', 'account', 'mi cuenta']
Defining Routes
Static Route Array
import { NavaiRoute } from '@navai/voice-frontend';
const APP_ROUTES: NavaiRoute[] = [
{
name: 'home',
path: '/',
description: 'Main landing page'
},
{
name: 'dashboard',
path: '/dashboard',
description: 'Analytics and metrics dashboard'
},
{
name: 'profile',
path: '/profile',
description: 'User profile and settings',
synonyms: ['account', 'settings', 'preferences']
},
{
name: 'reports',
path: '/reports',
description: 'Financial reports and documents',
synonyms: ['documents', 'files']
}
];
Routes Module
Create a dedicated routes file:
// src/ai/routes.ts
import { NavaiRoute } from '@navai/voice-frontend';
export const NAVAI_ROUTE_ITEMS: NavaiRoute[] = [
{
name: 'home',
path: '/',
description: 'Home page'
},
{
name: 'products',
path: '/products',
description: 'Product catalog',
synonyms: ['catalog', 'items', 'shop']
},
{
name: 'cart',
path: '/cart',
description: 'Shopping cart',
synonyms: ['basket', 'checkout']
},
{
name: 'orders',
path: '/orders',
description: 'Order history',
synonyms: ['purchases', 'history']
}
];
// Alternative export names also work:
// export const NAVAI_ROUTES = [...];
// export const APP_ROUTES = [...];
// export const routes = [...];
// export default [...];
Using Routes with Hook
import { useWebVoiceAgent } from '@navai/voice-frontend';
import { APP_ROUTES } from './ai/routes';
function VoiceNav() {
const navigate = useNavigate();
const { start } = useWebVoiceAgent({
navigate,
defaultRoutes: APP_ROUTES,
moduleLoaders: {}
});
return <button onClick={start}>Start Voice</button>;
}
Route Resolution
resolveNavaiRoute
Resolves voice input to a route path using fuzzy matching.
import { resolveNavaiRoute } from '@navai/voice-frontend';
const routes = [
{ name: 'profile', path: '/profile', description: 'Profile page', synonyms: ['account'] },
{ name: 'settings', path: '/settings', description: 'Settings' }
];
// Exact path match
resolveNavaiRoute('/profile', routes); // '/profile'
// Exact name match
resolveNavaiRoute('profile', routes); // '/profile'
// Synonym match
resolveNavaiRoute('account', routes); // '/profile'
// Partial match
resolveNavaiRoute('prof', routes); // '/profile'
// Case-insensitive, accent-insensitive
resolveNavaiRoute('PROFILE', routes); // '/profile'
resolveNavaiRoute('perfil', routes); // null (no match)
// Unknown route
resolveNavaiRoute('unknown', routes); // null
Type Signature
function resolveNavaiRoute(
input: string,
routes: NavaiRoute[]
): string | null;
Resolution Strategy
Exact Path Match
Checks if input matches any route’s path exactly (normalized).resolveNavaiRoute('/settings', routes); // matches path
Exact Name Match
Checks if input matches any route’s name exactly (normalized).resolveNavaiRoute('settings', routes); // matches name
Synonym Match
Checks if input matches any route’s synonym exactly (normalized).resolveNavaiRoute('preferences', routes); // matches synonym
Partial Name Match
Checks if any route’s name contains the input (normalized).resolveNavaiRoute('sett', routes); // matches partial 'settings'
Partial Synonym Match
Checks if any route’s synonym contains the input (normalized).resolveNavaiRoute('pref', routes); // matches partial 'preferences'
No Match
Returns null if no route matches.resolveNavaiRoute('nonexistent', routes); // null
Normalization
Route resolution normalizes input by:
- Converting to lowercase
- Removing accents (NFD normalization)
- Trimming whitespace
// All resolve to the same route
resolveNavaiRoute('Profile', routes);
resolveNavaiRoute('PROFILE', routes);
resolveNavaiRoute(' profile ', routes);
Prompt Generation
getNavaiRoutePromptLines
Generates human-readable route descriptions for the agent’s system prompt.
import { getNavaiRoutePromptLines } from '@navai/voice-frontend';
const routes = [
{
name: 'home',
path: '/',
description: 'Home page'
},
{
name: 'profile',
path: '/profile',
description: 'User profile',
synonyms: ['account', 'settings']
}
];
const lines = getNavaiRoutePromptLines(routes);
// [
// '- home (/)',
// '- profile (/profile), aliases: account, settings'
// ]
Type Signature
function getNavaiRoutePromptLines(routes: NavaiRoute[]): string[];
Usage in Agent Builder
This function is used internally by buildNavaiAgent to construct the agent’s instructions:
// Internal usage (from agent.ts)
const routeLines = getNavaiRoutePromptLines(options.routes);
const instructions = [
'You are a voice assistant embedded in a web app.',
'Allowed routes:',
...routeLines,
'Rules:',
'- If user asks to go/open a section, always call navigate_to.',
'- Never invent routes that are not listed.'
].join('\n');
Real-World Examples
E-Commerce App
const STORE_ROUTES: NavaiRoute[] = [
{
name: 'home',
path: '/',
description: 'Store homepage'
},
{
name: 'products',
path: '/products',
description: 'Browse all products',
synonyms: ['catalog', 'shop', 'store', 'items']
},
{
name: 'cart',
path: '/cart',
description: 'Shopping cart',
synonyms: ['basket', 'bag']
},
{
name: 'checkout',
path: '/checkout',
description: 'Checkout and payment',
synonyms: ['pay', 'payment', 'purchase']
},
{
name: 'orders',
path: '/orders',
description: 'Order history and tracking',
synonyms: ['purchases', 'history']
},
{
name: 'account',
path: '/account',
description: 'Account settings',
synonyms: ['profile', 'settings', 'preferences']
}
];
Dashboard App
const DASHBOARD_ROUTES: NavaiRoute[] = [
{
name: 'overview',
path: '/dashboard',
description: 'Main dashboard overview',
synonyms: ['home', 'main', 'dashboard']
},
{
name: 'analytics',
path: '/dashboard/analytics',
description: 'Analytics and metrics',
synonyms: ['stats', 'statistics', 'metrics']
},
{
name: 'reports',
path: '/dashboard/reports',
description: 'Generated reports',
synonyms: ['documents', 'files']
},
{
name: 'users',
path: '/dashboard/users',
description: 'User management',
synonyms: ['accounts', 'people', 'team']
},
{
name: 'settings',
path: '/dashboard/settings',
description: 'Application settings',
synonyms: ['config', 'configuration', 'preferences']
}
];
Multilingual App
const MULTILINGUAL_ROUTES: NavaiRoute[] = [
{
name: 'home',
path: '/',
description: 'Home page',
synonyms: ['inicio', 'accueil', 'home'] // Spanish, French, English
},
{
name: 'profile',
path: '/profile',
description: 'User profile',
synonyms: [
'perfil', // Spanish
'profil', // French
'account', // English
'mi cuenta', // Spanish
'mon compte' // French
]
},
{
name: 'settings',
path: '/settings',
description: 'Settings',
synonyms: [
'configuración', // Spanish
'paramètres', // French
'ajustes' // Spanish
]
}
];
Best Practices
Use Clear, Descriptive Names
Choose route names that match how users naturally refer to pages.// Good
{ name: 'profile', path: '/profile', description: 'User profile' }
// Avoid
{ name: 'usr_prof', path: '/profile', description: 'Profile' }
Include Common Synonyms
Add alternative names users might say.{
name: 'cart',
synonyms: ['basket', 'bag', 'shopping cart']
}
Write Helpful Descriptions
Descriptions help the agent understand context.// Good
description: 'Shopping cart with selected items and checkout options'
// Less helpful
description: 'Cart'
Support Multiple Languages
For international apps, include translations in synonyms.{
name: 'settings',
synonyms: ['configuración', 'paramètres', 'preferences']
}
Test Route Resolution
Manually test common voice inputs to ensure routes resolve correctly.console.log(resolveNavaiRoute('go to profile', routes));
console.log(resolveNavaiRoute('open settings', routes));
The voice agent uses the navigate_to tool to handle navigation commands. This tool:
- Receives voice input from the user (e.g., “go to profile”)
- Calls
resolveNavaiRoute(input, routes) to find matching path
- If resolved, calls
navigate(path) function
- Returns success or error message
// Internal implementation (from agent.ts)
const navigateTool = tool({
name: 'navigate_to',
description: 'Navigate to an allowed route in the current app.',
parameters: z.object({
target: z.string().min(1).describe('Route name or route path')
}),
execute: async ({ target }) => {
const path = resolveNavaiRoute(target, options.routes);
if (!path) {
return { ok: false, error: 'Unknown or disallowed route.' };
}
options.navigate(path);
return { ok: true, path };
}
});
The agent is instructed to always use navigate_to when the user asks to go to a section. You don’t need to handle navigation manually.