Nuxt Routing Basics
Nuxt is a modern framework built on top of Vue.js, designed for server-side rendering (SSR) and static site generation (SSG). In Nuxt 3, the routing system has been further streamlined and enhanced. It adopts a file-system-based routing mechanism, meaning that you simply need to create Vue components within designated directories, and Nuxt will automatically generate the corresponding route configurations for you.
This guide will walk you through the fundamentals of Nuxt routing from scratch, covering basic routes, dynamic routes, nested routes, and navigation techniques.
One of Nuxt's core features is file-system routing. All page components must be placed within the app/pages directory (or simply the pages directory at the root level). Nuxt reads this directory structure and automatically configures vue-router behind the scenes.
For example, consider the following project file structure:
pages/
--| about.vue
--| index.vue
The corresponding route mapping will be:
/maps topages/index.vue/aboutmaps topages/about.vue
Basic Page Example
Open pages/index.vue and write a standard Vue Single File Component:
<template>
<div>
<h1>Welcome to the Home Page</h1>
<p>This is a guide to Nuxt routing fundamentals.</p>
</div>
</template>
As soon as you save the file and visit the root path of your application, you will immediately see the rendered content.
Dynamic Routes
In real-world applications, you frequently need to handle paths with dynamic parameters, such as a user profile page at /users/1 or a blog post at /posts/vue-routing. Nuxt supports dynamic routes by enclosing file or folder names in square brackets [].
Capturing Single Dynamic Parameters
If your directory structure looks like this:
pages/
--| users/
----| [id].vue
Visiting either /users/1 or /users/abc will match the pages/users/[id].vue component. Inside the component, you can retrieve the value of the dynamic parameter using the useRoute composable:
<script setup lang="ts">
const route = useRoute()
// Log the current id parameter
console.log(route.params.id)
</script>
<template>
<div>
<h1>User Detail Page</h1>
<p>The current user ID is: {{ route.params.id }}</p>
</div>
</template>
Optional and Catch-All Routes
- Optional Parameters: By using double square brackets like
[[id]], you can define optional parameters that match both/usersand/users/1. - Catch-All Routes: Using
[name].vueor[...slug].vueallows you to capture all nested paths, which is commonly used for building 404 error pages or complex documentation directories.
Nested Routes
When your pages share a common layout while certain sections dynamically change based on child routes, you need nested routes.
To implement nested routes, follow these steps:
- Create a folder with the same name as the parent route.
- Inside that folder, create an
index.vue(serving as the default content for the parent route) or a parent component matching the folder name. - Use the
<NuxtPage>component as a placeholder for the child routes.
Directory structure example:
pages/
--| settings.vue
--| settings/
----| profile.vue
----| password.vue
For settings.vue to render its child routes correctly, its template must include <NuxtPage />:
<!-- pages/settings.vue -->
<template>
<div class="settings-layout">
<h2>Settings Center</h2>
<nav>
<NuxtLink to="/settings/profile">Profile</NuxtLink> |
<NuxtLink to="/settings/password">Change Password</NuxtLink>
</nav>
<hr />
<!-- Child pages will be rendered here -->
<NuxtPage />
</div>
</template>
When navigating to /settings/profile, the contents of pages/settings/profile.vue will be rendered right inside the <NuxtPage /> slot of pages/settings.vue.
Navigation
When navigating between pages in a Nuxt application, traditional HTML <a href="..."> tags are discouraged because they trigger a full-page reload. Instead, Nuxt provides specialized components and programmatic navigation methods.
Using the NuxtLink Component
<NuxtLink> is a wrapper around Vue Router's <RouterLink>, supporting features like prefetching and performance optimizations out of the box.
<template>
<nav>
<!-- Static route navigation -->
<NuxtLink to="/">Home</NuxtLink>
<!-- Dynamic route navigation -->
<NuxtLink :to="`/users/${userId}`">User Profile</NuxtLink>
<!-- Navigation using an object format -->
<NuxtLink :to="{ name: 'users-id', params: { id: 123 } }">
User 123
</NuxtLink>
</nav>
</template>
<script setup lang="ts">
const userId = 42
</script>
Programmatic Navigation
If you need to trigger a page transition inside an event handler (such as after a button click or successful form submission), you can use the navigateTo utility function:
<script setup lang="ts">
const router = useRouter()
const handleLogin = async () => {
// Perform login logic...
// Approach 1: Using Nuxt's built-in navigateTo
await navigateTo('/dashboard')
// Approach 2: Using vue-router's push method
// router.push('/dashboard')
}
</script>
<template>
<button @click="handleLogin">Log In</button>
</template>
Summary
Nuxt's routing system dramatically boosts development efficiency. Through this guide, you have learned:
- How file-system routing automatically configures routes based on the
pages/directory structure. - How to handle dynamic parameters using files like
[id].vue. - How to implement nested routes using identically named folders and the
<NuxtPage>component. - How to perform seamless page transitions via
<NuxtLink>andnavigateTo.
Armed with these fundamentals, you are well-equipped to build modern Nuxt web applications featuring multi-level pages and complex parameter interactions.