What Causes This Warning?
This warning appears when your dynamic route parameter (the part in square brackets) contains characters that aren’t valid for route parameter names.
The Problem
pages/
├── products/
│ ├── [product-id].vue ❌ Hyphen not allowed
│ ├── [product.id].vue ❌ Dot not allowed
│ ├── [product id].vue ❌ Space not allowed
│ └── [product@id].vue ❌ @ not allowed
The Fix
Use Valid Characters
pages/
├── products/
│ ├── [productId].vue ✅ camelCase
│ ├── [product_id].vue ✅ Underscore allowed
│ ├── [id].vue ✅ Simple name
│ └── [productID].vue ✅ PascalCase
Valid vs Invalid Characters
Valid
- Letters:
a-z,A-Z - Numbers:
0-9(not at start) - Underscore:
_
Invalid
- Hyphen:
- - Dot:
. - Space:
- Special characters:
@,#,$, etc.
Examples
Product Routes
pages/
├── products/
│ ├── [id].vue ✅ /products/123
│ ├── [productId].vue ✅ /products/abc123
│ └── [slug].vue ✅ /products/blue-widget
User Routes
pages/
├── users/
│ ├── [userId].vue ✅ /users/123
│ └── [username].vue ✅ /users/john_doe
Multi-Segment Catch-All
pages/
├── [...slug].vue ✅ Catches all remaining segments
├── [...path].vue ✅ Alternative name
└── docs/
└── [...slug].vue ✅ /docs/getting-started/installation
Accessing Route Parameters
<!-- pages/products/[productId].vue -->
<script setup>
const route = useRoute()
// Access the parameter
const productId = route.params.productId
// With TypeScript
const productId = route.params.productId as string
</script>
<template>
<h1>Product: {{ productId }}</h1>
</template>
Multiple Parameters
pages/
├── [category]/
│ └── [productId].vue ✅ /electronics/123
<!-- pages/[category]/[productId].vue -->
<script setup>
const route = useRoute()
const category = route.params.category // 'electronics'
const productId = route.params.productId // '123'
</script>
Optional Parameters
pages/
├── [[optionalId]].vue ✅ / or /123
<!-- pages/[[optionalId]].vue -->
<script setup>
const route = useRoute()
// May or may not exist
const id = route.params.optionalId // undefined or '123'
</script>
URL Formatting vs Parameter Names
The parameter NAME must be valid, but the actual URL VALUE can contain any characters:
<!-- pages/products/[slug].vue -->
<script setup>
const route = useRoute()
// Parameter name: slug (valid)
// URL value: 'blue-widget-2024' (can have hyphens)
const slug = route.params.slug // 'blue-widget-2024'
</script>
URL: /products/blue-widget-2024
↓
pages/products/[slug].vue
↓
route.params.slug = 'blue-widget-2024'
Migration from Invalid Names
Before (Invalid)
pages/
└── products/
└── [product-id].vue ❌
After (Valid)
pages/
└── products/
└── [productId].vue ✅
Update code references:
<script setup>
const route = useRoute()
// Before
// const id = route.params['product-id']
// After
const id = route.params.productId
</script>
TypeScript Route Typing
// types/router.d.ts
declare module 'vue-router' {
interface RouteParams {
productId?: string
categorySlug?: string
userId?: string
}
}
Quick Reference
| File Name | Valid? | URL Example |
|---|---|---|
[id].vue | ✅ | /123 |
[productId].vue | ✅ | /abc123 |
[product_id].vue | ✅ | /abc_123 |
[product-id].vue | ❌ | - |
[product.id].vue | ❌ | - |
[...slug].vue | ✅ | /a/b/c |
Quick Checklist
- Parameter names use only letters, numbers, underscores
- No hyphens in parameter names (use camelCase)
- No dots or special characters
- Numbers don’t start the parameter name
- Update code when renaming parameters
- Remember: URL values CAN have special characters