What Causes This Error?
This error occurs when you manually define a route path that doesn’t start with a forward slash (/). Vue Router requires all absolute route paths to begin with /.
The Problem
// ❌ Wrong - missing leading slash
const routes = [
{ path: 'about', component: About },
{ path: 'products', component: Products }
]
// In Nuxt pages directory:
// pages/
// └── about.vue ← This is fine, Nuxt handles it
//
// But manual route configuration needs /
The Fix
Add Leading Slash
// ✅ Correct
const routes = [
{ path: '/about', component: About },
{ path: '/products', component: Products }
]
In Nuxt Context
File-Based Routes (Automatic)
Nuxt automatically generates correct routes from your pages/ directory:
pages/
├── index.vue → /
├── about.vue → /about
├── products/
│ ├── index.vue → /products
│ └── [id].vue → /products/:id
Manual Route Extension
// nuxt.config.ts
export default defineNuxtConfig({
hooks: {
'pages:extend'(pages) {
// ✅ Correct - leading slash
pages.push({
path: '/custom-page',
file: '~/pages/custom.vue'
})
// ❌ Wrong - missing slash
pages.push({
path: 'another-page', // Error!
file: '~/pages/another.vue'
})
}
}
})
Route Rules
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// ✅ Correct - leading slash
'/api/**': { proxy: 'https://api.example.com/**' },
'/admin/**': { ssr: false },
// ❌ Wrong - missing slash
'products/**': { prerender: true } // Error!
}
})
Nested Routes
Child Routes
Child routes can omit the leading slash (they’re relative to parent):
const routes = [
{
path: '/products', // ✅ Parent needs slash
component: ProductsLayout,
children: [
{ path: '', component: ProductsList }, // ✅ OK (relative)
{ path: ':id', component: ProductDetail }, // ✅ OK (relative)
{ path: 'new', component: NewProduct } // ✅ OK (relative)
]
}
]
In Nuxt, nested routes work via folder structure:
pages/
└── products/
├── index.vue → /products
├── [id].vue → /products/:id
└── new.vue → /products/new
Router Module Configuration
// modules/custom-routes.ts
export default defineNuxtModule({
setup(options, nuxt) {
nuxt.hook('pages:extend', (pages) => {
pages.push({
path: '/my-route', // ✅ Always use leading slash
name: 'my-route',
file: resolve('./runtime/pages/MyPage.vue')
})
})
}
})
Programmatic Navigation
<script setup>
const router = useRouter()
// ✅ These all work correctly
router.push('/about')
router.push({ path: '/products' })
router.push({ name: 'products-id', params: { id: '123' } })
// ❌ These might cause issues
router.push('about') // Relative navigation - might not work as expected
</script>
NuxtLink Usage
<template>
<!-- ✅ Correct -->
<NuxtLink to="/about">About</NuxtLink>
<NuxtLink to="/products/123">Product</NuxtLink>
<!-- ✅ Named routes also work -->
<NuxtLink :to="{ name: 'products-id', params: { id: '123' } }">
Product
</NuxtLink>
<!-- ⚠️ Without slash, treated as relative -->
<NuxtLink to="about">About (relative)</NuxtLink>
</template>
Catch-All Routes
// ✅ Correct catch-all
const routes = [
{ path: '/:pathMatch(.*)*', component: NotFound }
]
// In Nuxt pages:
// pages/[...slug].vue → /:pathMatch(.*)*
Quick Examples
| Path | Valid? | Result |
|---|---|---|
/about | ✅ | Absolute route to /about |
/products/:id | ✅ | Dynamic route |
about | ⚠️ | Relative (needs parent) |
:id | ⚠️ | Relative (needs parent) |
* | ✅ | Wildcard (special case) |
Debugging
// Check registered routes
const router = useRouter()
console.log(router.getRoutes().map(r => ({
path: r.path,
name: r.name
})))
Quick Checklist
- All top-level route paths start with
/ - Child/nested routes can be relative (no
/) -
routeRuleskeys start with/ - Manual
pages:extendroutes have leading/ - NuxtLink
toprop uses/for absolute paths - Programmatic navigation uses
/or named routes