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.
Prerequisites
Section titled “Prerequisites”Before starting, make sure you have an Avenx-JS project initialized using the CLI:
npx avenx init my-router-appcd my-router-appStep 1: Create Page Components
Section titled “Step 1: Create Page Components”In Avenx-JS, top-level view views are stored as Page components in src/pages/. Use the CLI generator to scaffold your pages:
npx avenx g page homenpx avenx g page profilenpx avenx g page loginnpx avenx g page not-foundStep 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:
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 componentsapp.registerPage('Home', Home);app.registerPage('Profile', Profile);app.registerPage('Login', Login);app.registerPage('NotFound', NotFound);
// 2. Initialize router configurationapp.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:
<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>Step 4: Programmatic Navigation
Section titled “Step 4: Programmatic Navigation”In addition to standard HTML hash links (<a href="#/profile/42">), you can trigger navigation programmatically inside component actions using this.$router.navigate(hash):
<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:
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 }}Step 6: Testing Your App
Section titled “Step 6: Testing Your App”Start the local dev server:
npx avenx serve- Open
http://localhost:3000/#/. You will see the Home page. - Try navigating directly to
http://localhost:3000/#/profile/42. Becausewindow.isLoggedInis false,AuthGuardautomatically redirects you to#/login! - Click Log In on the Login page. The
handleLoginaction setswindow.isLoggedIn = trueand programmatically navigates to#/profile/42. - Try typing an unknown hash like
http://localhost:3000/#/unknown/page. The wildcard*route resolves and renders the NotFound 404 page!