How Vue Router Is Configured for Quiz App Lesson Navigation in AI-For-Beginners

The quiz application in microsoft/AI-For-Beginners uses Vue Router with history mode, dynamic route parameters, and a catch-all fallback to enable clean URL navigation between lessons.

The repository's quiz application—located in etc/quiz-app/—demonstrates a practical Vue.js single-page application (SPA) pattern for educational content. This article explains how Vue Router configuration enables seamless lesson-to-lesson navigation using dynamic routing and deep-linkable URLs.


Router Configuration Overview

The router is defined in src/router/index.js and exported as the application's central navigation controller. According to the AI-For-Beginners source code, this file sets three critical pieces of behavior: history mode for clean URLs, base path resolution from environment variables, and a route table with dynamic parameter capture.


History Mode and Base URL

The router initializes with options that modernize URL handling:

// src/router/index.js (lines 9-11)
const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [...]
})

mode: 'history' eliminates hash-based URLs (/#/quiz/3) in favor of clean paths (/quiz/3). The base property ensures correct asset resolution when the app is deployed to a subdirectory or custom domain.


Route Definitions for Lesson Navigation

Three routes handle all navigation scenarios in the quiz app:

Home Route

// src/router/index.js (lines 13-16)
{
  path: '/',
  name: 'home',
  component: Home
}

The home route serves as the entry point, listing all available lessons for selection.

Dynamic Quiz Route

// src/router/index.js (lines 18-21)
{
  path: '/quiz/:id',
  name: 'Quiz',
  component: Quiz
}

This dynamic route is the core of lesson navigation in the Vue Router configuration. The :id parameter captures any lesson identifier, enabling URLs like /quiz/1, /quiz/3, or /quiz/12. The Quiz.vue component receives this parameter via $route.params.id to load the appropriate quiz data.

Not Found Fallback

// src/router/index.js (lines 23-26)
{
  path: '/:pathMatch(.*)*',
  name: 'NotFound',
  component: NotFound
}

The catch-all route ensures users see a friendly error page instead of a broken view when accessing undefined URLs.


A global beforeEach guard is registered but kept minimal for future extension:

// src/router/index.js (lines 31-33)
router.beforeEach((to, from, next) => {
  next()
})

This hook executes before every route transition. While currently a no-op, it provides the extension point for authentication checks, analytics tracking, or dynamic title updates as quiz features expand.


Practical Navigation Patterns

In Home.vue, lessons are rendered as clickable links:

<ul>
  <li v-for="lesson in lessons" :key="lesson.id">
    <router-link :to="{ name: 'Quiz', params: { id: lesson.id } }">
      {{ lesson.title }}
    </router-link>
  </li>
</ul>

Using named routes with params ensures URL generation stays synchronized with the route definition.

Programmatic Navigation

Components can trigger navigation via the router instance:

export default {
  methods: {
    startQuiz(lessonId) {
      this.$router.push({ name: 'Quiz', params: { id: lessonId } })
    }
  }
}

Accessing Route Parameters

Inside Quiz.vue, the lesson identifier is retrieved reactively:

export default {
  computed: {
    quizId() {
      return this.$route.params.id   // e.g., "3" for lesson 3
    }
  }
}

Key Files in the Navigation System

File Purpose
etc/quiz-app/src/router/index.js Vue Router configuration, route definitions, navigation guard
etc/quiz-app/src/views/Home.vue Lesson listing and entry point
etc/quiz-app/src/components/Quiz.vue Dynamic quiz rendering for /quiz/:id
etc/quiz-app/src/views/NotFound.vue 404 fallback view

Summary

  • History mode enables clean, shareable URLs without hash fragments
  • Dynamic route parameter :id powers lesson-specific quiz access
  • Named routes (home, Quiz, NotFound) decouple links from URL paths
  • Global navigation guard provides extension hooks for future features
  • Catch-all route ensures graceful handling of undefined URLs

Frequently Asked Questions

What URL pattern does the quiz app use for individual lessons?

The quiz app uses /quiz/:id where :id is a dynamic segment capturing the lesson number. For example, navigating to /quiz/3 loads the quiz for lesson 3, with the value accessible inside Quiz.vue via this.$route.params.id.

Why does the router use mode: 'history' instead of hash mode?

History mode produces clean URLs without the # character, making links more readable, shareable, and SEO-friendly. The configuration requires server support to handle direct navigation to deep links, which is standard for modern deployment platforms.

How can I add page titles that update with each route?

Extend the existing beforeEach guard in src/router/index.js:

router.beforeEach((to, from, next) => {
  document.title = to.meta.title || 'AI Quiz App'
  next()
})

Add meta: { title: 'Lesson 3 Quiz' } to route objects to specify custom titles.

What happens if a user visits a non-existent lesson URL?

The catch-all route /:pathMatch(.*)* intercepts any unmatched paths and renders NotFound.vue. This prevents application crashes and provides a consistent user experience for invalid URLs.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →