enrutado-ficheros-con-unplugin-vue-router

File-based Routing with Unplugin Vue Router in Vue

  • 5 min

Unplugin Vue Router is a plugin for Vue.js that allows you to automatically generate file-based routing.

File-based routing is a pattern that automates route generation based on your project’s directory structure.

This means that the folder and file structure directly reflects your application’s navigation. This eliminates the need to manually maintain route configuration files.

It’s similar to how frameworks like Nuxt.js or Next.js work, but without needing to use a meta-framework.

Basic Installation and Configuration

To install Unplugin Vue Router in our project (which already has Vue Router installed) we do the following.

npm install unplugin-vue-router --save-dev  
Copied!

Now to configure it

Add the plugin to the Vite configuration in vite.config.ts

import { defineConfig } from 'vite'  
import Vue from '@vitejs/plugin-vue'
import VueRouter from 'unplugin-vue-router/vite'

export default defineConfig({
  plugins: [
    VueRouter({
      routesFolder: 'src/pages', // Routes folder
    }),
    Vue(), // Important: Vue() must come after!
  ],
})
Copied!

Now we initialize the plugin in main.ts (or equivalent),

import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router/auto' // Auto-imports the routes

const router = createRouter({
  history: createWebHistory(),
  // Routes are generated automatically!
})

const app = createApp(App)
app.use(router)
app.mount('#app')
Copied!

Unplugin Vue Router maintains compatibility with Vue Router. It’s not a replacement, but an extension.

Basic File Structure

Routes are generated automatically following simple conventions. For example,

src/ └── pages/ ├── index.vue # → / ├── contact.vue # → /contact └── about.vue # → /about

In this case

  • The route / would take you to the index.vue component
  • The route /contact would take you to the contact.vue component
  • The route /about would take you to the about.vue component

That easy 😉.

Nested Routes

Create subdirectories for nested routes. Each subdirectory inside /pages creates a new segment in the route. For example,

src/ └── pages/ ├── welcome.vue # → /welcome └── dashboard/ ├── settings.vue # → /dashboard/settings └── profile.vue # → /dashboard/profile

In this case,

  • The route /welcome will take you to welcome.vue
  • The route /dashboard/settings will take you to dashboard/settings.vue
  • The route /dashboard/profile will take you to dashboard/profile.vue

The Special Case of Index in Routes

You’ve seen that index has a somewhat special behavior. This file represents the base route of its directory. With this structure:

src/ └── pages/ ├── index.vue # → / └── dashboard/ └── index.vue # → /dashboard

  • The route / will take you to index.vue
  • The route /dashboard will take you to dashboard/index.vue

This is very common behavior in routing, file servers, etc.

Dynamic Routes and Parameters

For dynamic routes and parameters, Unplugin Vue Router uses brackets as placeholders for parameters,

  • [param].vue → Dynamic route (e.g., /users/123)

That is, the following folder structure

src/ └── pages/ └── users/ ├── [id].vue # → /users/└── index.vue # → /users

In this example, routes for the user system will be automatically generated:

  • users/index.vue → Route /users (user list).
  • users/[id].vue → Dynamic route /users/:id (details of a specific user).

You can use parameters in both file names and folders, and combine them at any nesting level to create the routes you need.

Accessing Parameters

We can access parameters in the same way we would normally do with Vue Router. For example, for pages/users/[id].vue

<script setup lang="ts">  
const route = useRoute('/users/[id]')  
console.log(route.params.id) // Type inferred as string  
</script>  
Copied!

Type Safety

The plugin generates TypeScript types for all routes in typed-router.d.ts, providing autocompletion and validation.

router.push('/users/123') // Autocompletion and validation
const { id } = route.params // Inferred type: `id: string`
Copied!

Catch-All Routes

For routes that need to capture multiple URL segments, we can use the [...slug].vue syntax,

  • [...slug].vue → Catch-all route

That is, for example the structure:

src/ └── pages/ └── docs/ └── […slug].vue # → /docs/*

The slug parameter will be an array with all route segments.

  • For example, /docs/a/b/c will capture ['a', 'b', 'c'] in params.slug

not-found Page

To handle non-existent routes, create a [...not-found].vue file at the root of pages/. This will capture any undefined route and display your custom 404 page.

src/ └── pages/ └── […not-found].vue

  • Any undefined URL (e.g., /non-existent/route) will display this component.
  • The URL segments are stored in route.params.notFound as an array.

Extending Routes Manually

We can also add additional routes, in case we need to customize any of them. To do this, we can edit the routes.ts file,

// src/routes.ts  
import { extendRoutes } from 'unplugin-vue-router'  

export default extendRoutes((routes) => {  
  routes.push({  
    path: '/custom',  
    component: () => import('./pages/custom.vue'),  
    meta: { requiresAuth: true }  
  })  
})  
Copied!