navigate
Programmatically navigate to routes with dynamic parameters, query strings, and history control.
API
function navigate(
pattern: string,
params?: Record<string, string>,
query?: Record<string, string>,
opts?: { replace?: boolean }
): void
Basic Usage
Use navigate
to trigger navigation from event handlers, effects, or anywhere in your application logic.
import { navigate } from "@hellajs/router";
// Navigate to a static path
navigate("/dashboard");
// Substitute route parameters
// Navigates to /posts/hello-world
navigate("/posts/:slug", { slug: "hello-world" });
// Add query parameters
// Navigates to /search?q=reactive
navigate("/search", {}, { q: "reactive" });
Key Concepts
History Management
navigate
integrates with the browser’s History API, pushing new entries by default or replacing them with the replace
option.
// Adds new history entry (user can go back)
navigate('/dashboard');
// Replaces current history entry (user cannot go back)
navigate('/dashboard', {}, {}, { replace: true });
Parameter Substitution
Route patterns with :param
placeholders use simple string replacement with automatic URL encoding. Understanding the exact behavior prevents navigation errors.
// Parameter substitution uses string.replace() with URL encoding
navigate('/users/:id/posts/:postId', {
id: '123',
postId: 'hello-world'
}); // Results in: /users/123/posts/hello-world
// Special characters are automatically URL-encoded
navigate('/search/:term', {
term: 'hello world & more!'
}); // Results in: /search/hello%20world%20%26%20more!
// Unused parameters are ignored silently
navigate('/users/:id', {
id: '123',
unusedParam: 'ignored' // This parameter is ignored
}); // Results in: /users/123
// Unmatched :param patterns are removed from URL
navigate('/users/:id/posts/:postId', {
id: '123'
// Missing postId parameter
}); // Results in: /users/123/posts/ (clean URL with removed param)
// Option 2: Using final URL directly (no substitution needed)
navigate('/users/123/posts/hello-world');
Important Parameter Behavior:
- Parameters are URL-encoded automatically
- Unused parameters are ignored (no error thrown)
- Missing parameters are removed from URL (
:param
patterns cleaned) - Parameter keys must exactly match the pattern placeholder names
Query String Handling
Query parameters are automatically serialized with URL encoding and appended to the final URL.
navigate('/search', {}, {
q: 'reactive',
category: 'frameworks',
page: '2'
}); // Results in: /search?q=reactive&category=frameworks&page=2
// Special characters in query values are URL-encoded
navigate('/search', {}, {
q: 'hello world & more',
filter: 'type=advanced'
}); // Results in: /search?q=hello%20world%20%26%20more&filter=type%3Dadvanced
// Empty query object results in no query string
navigate('/search', {}, {}); // Results in: /search
// Undefined/null query values are converted to strings
navigate('/search', {}, {
q: undefined,
page: null
}); // Results in: /search?q=undefined&page=null
Important Considerations
Asynchronous Navigation
Navigation is asynchronous - the route change isn’t immediate.
// ❌ Route may not be updated yet
navigate('/dashboard');
console.log(route().path);
// ✅ Use effect for route changes
effect(() => {
if (route().path === '/dashboard') {
console.log('Dashboard loaded');
}
});
Replace vs Push
Using replace: true
prevents users from navigating back to the previous page.
// ✅ Normal navigation - can go back
navigate('/new-page');
// ✅ Replace - overwrites history entry
navigate('/redirect', {}, {}, { replace: true });
Parameter Validation
The router performs no parameter validation - invalid keys are silently ignored and missing keys create malformed URLs.
// ✅ Correct parameter key
navigate('/users/:id', { id: '123' });
// Results in: /users/123
// ❌ Wrong key, param not substituted - gets removed
navigate('/users/:id', { userId: '123' });
// Results in: /users/ (param removed, likely unintended route)
// ❌ Missing required parameter - param gets removed
navigate('/users/:id/posts/:postId', { id: '123' });
// Results in: /users/123/posts/ (param removed, may not match intended route)
// ✅ Best practice: validate parameters before navigation
const navigateToUser = (userId) => {
if (!userId) {
console.error('User ID is required');
return;
}
navigate('/users/:id', { id: userId });
};
Parameter Validation Recommendations:
- Always validate parameters before calling
navigate()
- Use TypeScript for compile-time parameter checking
- Consider using helper functions for common navigation patterns
- Test navigation with missing/invalid parameters during development