Nuxt-Page
In a Nuxt application, pages serve as the foundational building blocks for your user interface. Nuxt relies on a file-system-based routing architecture. By simply organizing component files inside the pages/ directory following a few intuitive conventions, the framework automatically generates the underlying Vue Router configuration. This eliminates the tedious task of manually maintaining a centralized routing table. Embracing a "convention over configuration" philosophy, this approach significantly reduces boilerplate and streamlines route management.
To activate the page routing system, create a pages/ directory at your project root and place the <NuxtPage /> component inside your app.vue file. This component acts as the rendering outlet for all matched pages:
<template>
<div>
<NuxtPage />
</div>
</template>
The file structure maps directly to URL paths in a predictable manner:
pages/
├── index.vue → /
├── about.vue → /about
└── users/
├── index.vue → /users
└── list.vue → /users/list
An index.vue file corresponds to the root path of its respective directory, serving as the default entry point for that segment.
Modern web applications frequently require rendering pages based on dynamic segments, such as individual product profiles or user profiles. Nuxt handles dynamic routing by wrapping filenames in square brackets:
[id].vue: Matches single-segment paths like/products/1or/products/abc.[...slug].vue: Catch-all routes that match multi-segment paths, frequently utilized for custom 404 error pages.
Within your component, route parameters can be easily accessed using the useRoute() composable:
<script setup>
const route = useRoute()
const id = route.params.id
</script>
<template>
<h1>Product Details: {{ id }}</h1>
</template>
Furthermore, you can validate route parameters directly inside a page using the validate function. If validation fails, Nuxt automatically triggers a page error:
definePageMeta({
validate: route => /^\d+$/.test(route.params.id as string)
})
Configuring Page Metadata with definePageMeta
definePageMeta is a compile-time macro specifically designed to attach metadata to individual pages. Common configuration options include:
layout: Specifies the layout component wrapping the page.middleware: Assigns route middleware to handle pre-navigation logic such as authentication checks.keepalive: Caches the page component state when switching between routes.key: Controls when the page component should be completely re-rendered.
Example usage:
<script setup lang="ts">
definePageMeta({
layout: 'dashboard',
middleware: ['auth'],
keepalive: true
})
</script>
Using middleware: ['auth'] executes the named middleware located in middleware/auth.ts, allowing you to verify user authentication status prior to entering the page and redirecting unauthenticated users accordingly.
Navigation Methods
Navigating between pages is typically handled through two primary approaches:
- Declarative Navigation: Utilizing the
<NuxtLink>component. It intelligently prefetches target page data and assets in the background, ensuring a lightning-fast transition experience:
<NuxtLink to="/products/1">View Product</NuxtLink>
- Programmatic Navigation: Invoking
navigateTo()inside event handlers or asynchronous logic:
async function login() {
await doLogin()
return navigateTo('/dashboard')
}
Nested Pages
When your application features hierarchical layouts—such as a dashboard consisting of a persistent sidebar and a dynamic content area—nested routes provide an elegant solution. Place a <NuxtPage /> inside a parent component named parent.vue, and group the child pages within a directory bearing the same name:
pages/
├── parent.vue → /parent (Parent container shell)
└── parent/
├── a.vue → /parent/a
└── b.vue → /parent/b
When visiting /parent/a, the parent.vue layout remains active as the outer shell, while its internal <NuxtPage /> renders the content of a.vue. Shared interface elements like navigation bars or sidebars persist seamlessly across route transitions.
Conclusion
Nuxt's page architecture transforms simple directory structures into powerful routing systems. Combined with compile-time metadata, route middleware, robust parameter validation, and nested layouts, it effortlessly scales from straightforward landing pages to complex application interfaces. By mastering these intuitive conventions, developers can focus entirely on core business logic while letting the framework handle the complexities of route generation and management.