How to use
The module will automaticaly provide autocomplete and type-check for route path
, name
and params
.
Params autocomplete takes into account the way vue-router works (As navigating between children routes without re-providing the param).
The types from vue-router
and Nuxt navigation utils will be owerwritten, allowing for a safe navigation.
Examples for different pages structure
All those examples will be about files present in the pages
folder.
Basic path navigation
Path navigation will propose you the list of routes declaration to choose from, and will dynamically validate the route. It supports
- Query params
- Hash params
- Errors for invalid paths like
/foo /bar
or/foo////bar
<NuxtLink/>
the following Volar settings are injected into your .nuxt/tsconfig:- jsxTemplates
- experimentalRfc436
pages/login.vue
When a route has no params defined, the params
property will not even be available as an option in the router.
router.push('/login/bar'); // Error! ❌
router.push({name: 'login', params: {foo: 'bar'}}) // Error! ❌
router.push('/login'); // Good! ✅
router.push({name: 'login'}) // Good! ✅
Same with resolved routes, the params
property will not be available.
const route = useRoute();
if (route.name === 'login') {
console.log(route.params); // Error! ❌
}
pages/user/[id].vue
When a route has a required param defined, navigating exactly to this route will throw an error if you don't provide a params
property or if you put a wrong param.
router.push({name: 'user-id'}) // Error! ❌
router.push({name: 'user-id', params: {bar: 'baz'}}) // Error! ❌
router.push('/user') // Error! ❌
const id = "ey7878"
router.push(`/user/${id}`) // Good! ✅
router.push({name: 'user-id', params: {id}}) // Good! ✅
router.push(`/user/${id}/baguette`) // Error! ❌
For resolved routes, the params
property will be available and correctly typed.
const route = useRoute();
if (route.name === 'foo') {
console.log(route.params.baz); // Error! ❌
console.log(route.params.foo); // Good! ✅
}
useRoute
, there is an additional guard that can save you some unecessary check if you're confident on the page you're in. See useRoute docs for more info⬆️ Example:
const route = useRoute('foo');
console.log(route.params.baz); // Error! ❌
console.log(route.params.foo); // Good! ✅
pages/user/foo/[[bar]].vue
When a route has only an optional param defined, navigating exactly to this route will not require to provide a params
property, and will mark the bar
param as optional too.
router.push({name: 'user-foo-bar'}) // Good! ✅
router.push('/user/foo') // Good! ✅
router.push({name: 'user-foo-bar', params: {foo: 'baz'}}) // Error! ❌
router.push({name: 'user-foo-bar', params: {bar: 'baz'}}) // Good! ✅
router.push('/user/foo/baz') // Good! ✅
For resolved routes, the params
property will be available and correctly typed.
const route = useRoute();
if (route.name === 'bar') {
console.log(route.params.foo); // Error! ❌
console.log(route.params.bar); // Good! ✅ - params: {bar?: string | undefined}
}
pages/[title]-[[slug]].vue
When a route has both a required and an optional param defined, navigating exactly to this route will require to provide a params
property, and will mark the params accordingly.
router.push({name: 'title-slug'}) // Error! ❌
router.push({name: 'title-slug', params: {slug: 'baz'}}) // Error! ❌
router.push({name: 'title-slug', params: {title: 'Bonjour'}}) // Good! ✅
router.push({name: 'title-slug', params: {title: 'Bonjour', slug: 'baz'}}) // Good! ✅
router.push('/blabla-') // Good! ✅
router.push('/blabla-foo/bar') // Error! ❌
Fo resolved routes, the params
property will be available and correctly typed.
const route = useRoute();
if (route.name === 'title-slug') {
console.log(route.params.foo); // Error! ❌
console.log(route.params.title); // Good! ✅ - title: string
console.log(route.params.slug); // Good! ✅ - slug?: string | undefined
}
pages/[...options].vue
When you define a "catch-all" route, navigating exactly to this route will require to provide a params
property, and will need the param the be an Array
.
router.push({name: 'options'}) // Error! ❌
router.push({name: 'options', params: {options: 'baz'}}) // Error! ❌
router.push('/foo/bar/baz') // Good! ✅
router.push({name: 'options', params: {options: ['foo', 'bar']}}) // Good! ✅
router.push({name: 'options', params: {options: [1, 2, 3, 'foo']}}) // Good! ✅
For resolved routes, the params
property will be available and correctly typed.
const route = useRoute();
if (route.name === 'options') {
console.log(route.params.foo); // Error! ❌
console.log(route.params.options.join(',')); // Good! ✅ - options: string[]
}
pages/nested/[title]/user/[id]/index.vue
On a route with nested params, the logic will be a little different.
Because of vue-router
behave, you are not required to re-provide parent params.
Ex: navigating from routepages/nested/[title]/user/[id]/posts.vue
-> pages/nested/[title]/user/[id]/index.vue
, as [id]
is a required param, you will not have to pass title
and id
params.
As we cannot know where you are navigating from, the title
and id
params will be optional.
router.push('/nested/foo/user') // Error! ❌
router.push({name: 'nested-title-user-id'}) // Error! ❌
router.push({name: 'nested-title-user-id', params: {foo: 'baz'}}) // Error! ❌
router.push('/nested/foo/user/YUEUY77') // Good! ✅
router.push({name: 'nested-title-user-id', params: {id: 1}}) // Good! ✅
router.push({name: 'nested-title-user-id', params: {id: 1, title: 'foo'}}) // Good! ✅
As for resolved routes, the parameters will not be marqued as optional
const route = useRoute();
if (route.name === 'nested-title-user-id') {
console.log(route.params.foo); // Error! ❌
console.log(route.params.id); // Good! ✅ - id: string
console.log(route.params.title); // Good! ✅ - title: string
}