Skip to content

Routing & Navigation Tutorial

Client-side routing is essential for Single Page Applications (SPAs). In this step-by-step tutorial, you will learn how to set up AvenxRouter, map routes to page components, handle dynamic route parameters, perform programmatic navigation, and secure routes using route guards.


Before starting, make sure you have an Avenx-JS project initialized using the CLI:

Terminal window
npx avenx init my-router-app
cd my-router-app

In Avenx-JS, top-level view views are stored as Page components in src/pages/. Use the CLI generator to scaffold your pages:

Terminal window
npx avenx g page home
npx avenx g page profile
npx avenx g page login
npx avenx g page not-found

Step 2: Configure the Router (app.initRouter)

Section titled “Step 2: Configure the Router (app.initRouter)”

Open src/main.app.js to register your page components and initialize the router mapping:

src/main.app.js
import { AvenxApp } from 'avenx-core/runtime';
import Home from './pages/home.page.js';
import Profile from './pages/profile.page.js';
import Login from './pages/login.page.js';
import NotFound from './pages/not-found.page.js';
import AuthGuard from './guards/auth.guard.js';
const app = new AvenxApp({ target: '#app' });
// 1. Register page components
app.registerPage('Home', Home);
app.registerPage('Profile', Profile);
app.registerPage('Login', Login);
app.registerPage('NotFound', NotFound);
// 2. Initialize router configuration
app.initRouter(
{
'/': { page: 'Home', title: 'Home' },
'/login': { page: 'Login', title: 'Sign In' },
// Route with dynamic parameter and authentication guard
'/profile/:id': {
page: 'Profile',
title: (params) => `User Profile #${params.id}`,
guards: [AuthGuard],
},
// Catch-all 404 fallback route
'*': { page: 'NotFound', title: 'Page Not Found' },
},
{
titleSuffix: ' — My Avenx App',
}
);

Step 3: Extract Dynamic Route Parameters & Query Strings

Section titled “Step 3: Extract Dynamic Route Parameters & Query Strings”

Route parameters specified with a colon (e.g. :id) and query parameters (e.g. ?tab=settings) are automatically parsed and passed to page components.

Update src/pages/profile.page.js:

src/pages/profile.page.js
<state activeTab="'overview'" />
<action name="onMount">
// Access route params via state.id or this.$route.params.id
console.log(`Mounted profile page for user ID: ${this.state.id}`);
// Access query parameters (e.g. #/profile/42?tab=activity)
if (this.state.query && this.state.query.tab) {
this.state.activeTab = this.state.query.tab;
}
</action>
<div class="profile-page">
<h1>User Profile: #{{ id }}</h1>
<p>Active Tab: {{ activeTab }}</p>
<nav class="sub-nav">
<a href="#/profile/{{ id }}?tab=overview">Overview</a>
<a href="#/profile/{{ id }}?tab=activity">Activity</a>
</nav>
</div>

In addition to standard HTML hash links (<a href="#/profile/42">), you can trigger navigation programmatically inside component actions using this.$router.navigate(hash):

src/pages/login.page.js
<state username="''" password="''" />
<action name="handleLogin">
if (this.state.username === 'admin') {
window.isLoggedIn = true;
// Navigate programmatically to the dashboard/profile page
this.$router.navigate('#/profile/42');
} else {
alert('Invalid credentials!');
}
</action>
<div class="login-page">
<h2>Sign In</h2>
<button @click="handleLogin()">Log In</button>
</div>

Step 5: Protect Routes with Navigation Guards (AvenxGuard)

Section titled “Step 5: Protect Routes with Navigation Guards (AvenxGuard)”

Navigation guards intercept route changes to restrict access (for example, enforcing authentication).

Create src/guards/auth.guard.js by extending AvenxGuard:

src/guards/auth.guard.js
import { AvenxGuard } from 'avenx-core/runtime';
export default class AuthGuard extends AvenxGuard {
/**
* Evaluates navigation access before route activation.
* @param {object} to - Destination route object (#/profile/:id)
* @param {object} from - Source route object
* @returns {boolean|string} Returns true to allow, false to block, or hash path string to redirect.
*/
canActivate(to, from) {
// Check if user is authenticated
if (!window.isLoggedIn) {
console.warn('[AuthGuard] Access denied. Redirecting to login.');
// Redirect to login page
return '#/login';
}
return true; // Allow navigation
}
}

Start the local dev server:

Terminal window
npx avenx serve
  1. Open http://localhost:3000/#/. You will see the Home page.
  2. Try navigating directly to http://localhost:3000/#/profile/42. Because window.isLoggedIn is false, AuthGuard automatically redirects you to #/login!
  3. Click Log In on the Login page. The handleLogin action sets window.isLoggedIn = true and programmatically navigates to #/profile/42.
  4. Try typing an unknown hash like http://localhost:3000/#/unknown/page. The wildcard * route resolves and renders the NotFound 404 page!