### Start Development Server Source: https://github.com/posva/unplugin-vue-router/blob/main/examples/nuxt/README.md Launch the development server at http://localhost:3000. ```bash npm run dev ``` -------------------------------- ### Install Dependencies Source: https://github.com/posva/unplugin-vue-router/blob/main/examples/nuxt/README.md Install project dependencies using yarn, npm, or pnpm. ```bash # yarn yarn install # npm npm install # pnpm pnpm install --shamefully-hoist ``` -------------------------------- ### Route Manipulation with Layouts Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/introduction.md Example demonstrating how to integrate generated routes with layout setup, often used in starters like Vitesse. Note that type support for these manipulated routes might require build-time route generation. ```ts import { ViteSSG } from 'vite-ssg' import { setupLayouts } from 'virtual:generated-layouts' import App from './App.vue' import type { UserModule } from './types' import generatedRoutes from '~pages' // [!code --] import { routes } from 'vue-router/auto-routes' // [!code ++] import '@unocss/reset/tailwind.css' import './styles/main.css' import 'uno.css' const routes = setupLayouts(generatedRoutes) // [!code --] // https://github.com/antfu/vite-ssg export const createApp = ViteSSG( App, { routes, // [!code --] routes: setupLayouts(routes), // [!code ++] base: import.meta.env.BASE_URL, }, (ctx) => { // install all modules under `modules/` Object.values( import.meta.glob<{ install: UserModule }>('./modules/*.ts', { eager: true, }) ).forEach((i) => i.install?.(ctx)) } ) ``` -------------------------------- ### Setup DataLoaderPlugin Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Installs the DataLoaderPlugin before the router to ensure navigation guards are attached correctly. This plugin requires the router instance and an optional selectNavigationResult function. ```typescript import { createApp } from 'vue' import { createRouter } from 'vue-router' import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders' const router = createRouter({ // ... }) const app = createApp(App) app.use(DataLoaderPlugin, { router }) // add the router after the DataLoaderPlugin app.use(router) ``` -------------------------------- ### Install unplugin-vue-router Source: https://github.com/posva/unplugin-vue-router/blob/main/README.md Install the package as a development dependency. ```bash npm i -D unplugin-vue-router ``` -------------------------------- ### Example Component in a Route Group Source: https://context7.com/posva/unplugin-vue-router/llms.txt A component file located inside a route group folder. ```vue ``` -------------------------------- ### Integrate Generated Routes with Vitesse Starter Source: https://github.com/posva/unplugin-vue-router/blob/main/README.md This example shows how to integrate unplugin-vue-router with the Vitesse starter, including setupLayouts. Note the change in route import and how routes are passed to ViteSSG. ```diff import { ViteSSG } from 'vite-ssg' import { setupLayouts } from 'virtual:generated-layouts' import App from './App.vue' import type { UserModule } from './types' -import generatedRoutes from '~pages' +import { routes } from 'vue-router/auto-routes' import '@unocss/reset/tailwind.css' import './styles/main.css' import 'uno.css' -const routes = setupLayouts(generatedRoutes) // https://github.com/antfu/vite-ssg export const createApp = ViteSSG( App, { - routes, + routes: setupLayouts(routes), base: import.meta.env.BASE_URL }, (ctx) => { // install all modules under `modules/` Object.values(import.meta.glob<{ install: UserModule }>('./modules/*.ts', { eager: true })) .forEach(i => i.install?.(ctx)) }, ) ``` -------------------------------- ### Vue Query Demo Source: https://github.com/posva/unplugin-vue-router/blob/main/src/data-loaders/defineLoader-notes.md Demonstrates basic usage of `useQuery` from Vue Query within a Vue component. Ensure `vue-query` is installed and configured. ```vue ``` -------------------------------- ### Setup Data Loader Plugin for Vue Router Source: https://context7.com/posva/unplugin-vue-router/llms.txt Install and configure the DataLoader plugin before registering the router in your Vue application's main entry point. ```typescript // src/main.ts import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import { routes } from 'vue-router/auto-routes' import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders' import App from './App.vue' const router = createRouter({ history: createWebHistory(), routes, }) const app = createApp(App) // Register DataLoaderPlugin BEFORE the router app.use(DataLoaderPlugin, { router }) app.use(router) app.mount('#app') ``` -------------------------------- ### Basic Vue Router Setup Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/introduction.md Set up the Vue Router with history mode and import generated routes. This is typically done in your main application entry point. ```ts import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import { routes } from 'vue-router/auto-routes' import App from './App.vue' const router = createRouter({ history: createWebHistory(), routes, }) createApp(App) .use(router) .mount('#app') ``` -------------------------------- ### Implement manual data fetching with Suspense Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Demonstrates a basic data fetching pattern using top-level await in script setup, requiring manual implementation of reload logic. ```vue ``` ```vue ``` -------------------------------- ### Define Routes with Dot Notation Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Example showing how using a dot in a filename creates a nested URL path without nesting the UI component hierarchy. ```javascript const routes = [ { path: '/users', component: () => import('src/pages/users.vue'), children: [ { path: '', component: () => import('src/pages/users/index.vue') }, { path: ':id', component: () => import('src/pages/users/[id].vue') }, ], }, { path: '/users/create', component: () => import('src/pages/users.create.vue'), }, ] ``` -------------------------------- ### Setup Data Loader Plugin in Nuxt Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/nuxt.md Create a plugin in the plugins directory to register the DataLoaderPlugin with the Vue application instance. ```ts // plugins/data-loaders.ts import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders' export default defineNuxtPlugin({ name: 'data-loaders', dependsOn: ['nuxt:router'], setup(nuxtApp) { const appConfig = useAppConfig() nuxtApp.vueApp.use(DataLoaderPlugin, { router: nuxtApp.vueApp.config.globalProperties.$router, isSSR: import.meta.server, // other options... }) }, }) ``` -------------------------------- ### Define and consume a basic data loader Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/defining-loaders.md Example of defining a basic loader with defineBasicLoader and consuming its returned properties in a Vue component. ```vue ``` -------------------------------- ### Route Folders with Path Prefixes and Parameters Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Configure route folders with custom path prefixes, including parameters. Prefixes cannot start with '/' but can end with or without a '/'. ```ts import VueRouter from 'unplugin-vue-router/vite' // --- // @moduleResolution: bundler VueRouter({ routesFolder: [ 'src/pages', { src: 'src/admin/routes', // note there is always a trailing slash and never a leading one path: 'admin/', // src/admin/routes/dashboard.vue -> /admin/dashboard }, { src: 'src/docs', // you can add parameters path: 'docs/:lang/', // src/docs/introduction.vue -> /docs/:lang/introduction }, { src: 'src/promos', // you can omit the trailing slash path: 'promos-', // src/promos/black-friday.vue -> /promos-black-friday }, ], }) ``` -------------------------------- ### Define a loader with a key Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Example of defining a loader with a specific key for SSR serialization. ```ts export const useBookCollection = defineLoader( async () => { const books = await fetchBookCollection() return books }, { key: 'bookCollection' } ) ``` -------------------------------- ### Define Nested Routes with Component Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Example of a routes array generated when a folder and a file share the same name, creating a parent-child relationship. ```javascript const routes = [ { path: '/users', component: () => import('src/pages/users.vue'), children: [ { path: '', component: () => import('src/pages/users/index.vue') }, ], }, ] ``` -------------------------------- ### Update main.ts for Vue app setup Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/introduction.md Ensure your main.ts correctly imports and uses the router for your Vue application. ```typescript import { createApp } from 'vue' import { router } from './router' import App from './App.vue' createApp(App).use(router).mount('#app') ``` -------------------------------- ### Install DataLoaderPlugin before Router Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/index.md Register the DataLoaderPlugin before the router instance to enable data loading functionality. This ensures that the plugin is active when the router is initialized. ```typescript import 'unplugin-vue-router/client' import './typed-router.d' // @moduleResolution: bundler // ---cut--- import { createApp } from 'vue' import { routes } from 'vue-router/auto-routes' import { createRouter, createWebHistory } from 'vue-router' import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders' // [!code ++] const router = createRouter({ history: createWebHistory(), routes, }) const app = createApp({}) // Register the plugin before the router app.use(DataLoaderPlugin, { router }) // [!code ++] // adding the router will trigger the initial navigation app.use(router) app.mount('#app') ``` -------------------------------- ### Define a Pinia Colada loader Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Example of a loader using Pinia Colada that automatically refreshes based on route parameters. ```ts export const useUserData = defineColadaLoader(async (route) => { const user = await getUserById(route.params.id) return user }) ``` -------------------------------- ### Vue Component with ``` -------------------------------- ### Typing dynamically added routes with useRoute generics Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/typescript.md Demonstrates various ways to use the `useRoute` function with type parameters or string arguments to get typed route information, including child routes. The string argument method is recommended for its simplicity and autocompletion. ```typescript // ---cut-start--- import 'unplugin-vue-router/client' import './typed-router.d' import { useRoute, type RouteLocationNormalizedLoaded } from 'vue-router' // ---cut-end--- // @errors: 2322 2339 // @moduleResolution: bundler // These are all valid ways to get a typed route and return the // provided route's and any of its child routes' typings. // Note that `/users/[id]/edit` is a child route // of `/users/[id]` in this example. // Not recommended, since this leaves out any child routes' typings. const userRouteWithIdCasted = useRoute() as RouteLocationNormalizedLoaded<'/users/[id]'> userRouteWithIdCasted.params.id // Better way. Includes child routes' typings, but no autocompletion. const userRouteWithIdTypeParam = useRoute<'/users/[id]'>() userRouteWithIdTypeParam.params.id // ๐Ÿ‘‡ This one is the easiest to write because it both // autocompletes and includes child routes' typings. const userRouteWithIdParam = useRoute('/users/[id]') userRouteWithIdParam.name userRouteWithIdParam.params.id ``` -------------------------------- ### Configure route metadata with definePage Source: https://context7.com/posva/unplugin-vue-router/llms.txt Override route configuration directly within a Vue component's script setup block. ```vue ``` -------------------------------- ### VueFire Firestore Loader Source: https://github.com/posva/unplugin-vue-router/blob/main/src/data-loaders/defineLoader-notes.md Examples of using `defineFirestoreLoader` with VueFire. The loader can accept a function that returns a Firestore path or a document reference. ```typescript const useUserProfile = defineFirestoreLoader(to => ['users', to.params.id]) ``` ```typescript const useUserProfile = defineFirestoreLoader(to => doc(useFirestore(), 'users', to.params.id) ``` -------------------------------- ### Build and Preview Production Source: https://github.com/posva/unplugin-vue-router/blob/main/examples/nuxt/README.md Commands to generate a production build and preview the application locally. ```bash npm run build ``` ```bash npm run preview ``` -------------------------------- ### Configure Multiple Route Folders Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Provide an array to `routesFolder` to specify multiple directories for routes. Path prefixes can be defined for each folder. ```js VueRouter({ routesFolder: ['src/pages', 'src/admin/routes'], }) ``` -------------------------------- ### Catch All / 404 Route Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Prepend three dots (...) to a parameter name (e.g., [...path]) to create a catch-all route that matches any path. ```js src/pages/[...path].vue ``` ```js src/pages/articles/[...path].vue ``` -------------------------------- ### Initialize Router with Auto-Generated Routes Source: https://context7.com/posva/unplugin-vue-router/llms.txt Import auto-generated routes and enable HMR in the main entry file. ```typescript // src/main.ts import { createApp } from 'vue' import { createRouter, createWebHistory } from 'vue-router' import { routes, handleHotUpdate } from 'vue-router/auto-routes' import App from './App.vue' const router = createRouter({ history: createWebHistory(), routes, }) // Enable HMR for routes if (import.meta.hot) { handleHotUpdate(router) } createApp(App).use(router).mount('#app') ``` -------------------------------- ### Organize Routes with Route Groups Source: https://context7.com/posva/unplugin-vue-router/llms.txt Use parentheses in folder names to group files without affecting the URL path. ```text src/pages/ โ”œโ”€โ”€ (admin)/ โ”‚ โ”œโ”€โ”€ dashboard.vue # /dashboard โ”‚ โ””โ”€โ”€ settings.vue # /settings โ””โ”€โ”€ (user)/ โ”œโ”€โ”€ profile.vue # /profile โ””โ”€โ”€ orders.vue # /orders ``` -------------------------------- ### Runtime Route Extension (Layouts) Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/extending-routes.md Integrate with layout plugins like `vite-plugin-vue-layouts` by extending routes at runtime. The `setupLayouts` function processes the routes array to apply layout configurations. ```typescript import { createRouter } from 'vue-router' import { routes } from 'vue-router/auto-routes' import { setupLayouts } from 'virtual:generated-layouts' const router = createRouter({ // ... routes: setupLayouts(routes), }) ``` -------------------------------- ### View File-Based Routing Structure Source: https://context7.com/posva/unplugin-vue-router/llms.txt Visual representation of how file paths map to route paths. ```text src/pages/ โ”œโ”€โ”€ index.vue # / โ”œโ”€โ”€ about.vue # /about โ”œโ”€โ”€ users/ โ”‚ โ”œโ”€โ”€ index.vue # /users โ”‚ โ””โ”€โ”€ [id].vue # /users/:id โ”œโ”€โ”€ users.vue # Layout wrapper for /users/* โ”œโ”€โ”€ posts/ โ”‚ โ”œโ”€โ”€ [slug].vue # /posts/:slug โ”‚ โ””โ”€โ”€ [[category]].vue # /posts/:category? (optional param) โ”œโ”€โ”€ articles/ โ”‚ โ””โ”€โ”€ [slugs]+.vue # /articles/:slugs+ (repeatable param) โ”œโ”€โ”€ docs/ โ”‚ โ””โ”€โ”€ [[...path]].vue # /docs/:path* (optional catch-all) โ””โ”€โ”€ [...path].vue # /:path(.*) (404 catch-all) ``` -------------------------------- ### Define Basic Data Loader with unplugin-vue-router Source: https://context7.com/posva/unplugin-vue-router/llms.txt Create a basic data loader that executes on every navigation, fetching data before the component renders. Configure options like `lazy`, `server`, and `commit`. ```vue ``` -------------------------------- ### Define Nested Routes without Parent Component Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Example of a routes array generated when the parent component file is omitted, resulting in a nested route structure without a shared layout component. ```javascript const routes = [ { path: '/users', // notice how there is no component here children: [ { path: '', component: () => import('src/pages/users/index.vue') }, ], }, ] ``` -------------------------------- ### Dynamic Route Parameters Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Wrap parameter names in brackets (e.g., [id]) to create dynamic routes. Multiple parameters and parameters within static segments are supported. ```js src/pages/users/[id].vue ``` ```js src/pages/users_[id].vue ``` ```js src/pages/product_[skuId]_[seoDescription].vue ``` -------------------------------- ### Configure ESLint for definePage macro Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/eslint.md Add this to your ESLint configuration to inform ESLint about the global definePage macro, which is a global macro. ```json { "globals": { "definePage": "readonly" } } ``` -------------------------------- ### Runtime Route Extension (Redirects) Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/extending-routes.md Add redirect routes at runtime by pushing new route objects to the `routes` array. This allows for dynamic redirects based on parameters or specific paths. ```typescript import { routes } from 'vue-router/auto-routes' routes.push({ path: '/path-to-redirect', redirect: '/redirected-path', }) routes.push({ path: '/path-to-redirect/:id', redirect: (to) => `/redirected-path/${to.params.id}`, }) ``` -------------------------------- ### Configure Lazy Data Loaders Source: https://context7.com/posva/unplugin-vue-router/llms.txt Implements non-blocking data fetching using defineBasicLoader with various lazy configuration strategies. ```vue ``` -------------------------------- ### Define route configuration in SFC custom blocks Source: https://context7.com/posva/unplugin-vue-router/llms.txt Use the block to define metadata using JSON5 or YAML syntax directly in the SFC. ```vue { name: 'admin-dashboard', meta: { requiresAuth: true, layout: 'admin', }, } ``` ```vue name: settings-page meta: requiresAuth: true permissions: - read - write ``` -------------------------------- ### Sequential Loader Execution Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Demonstrates how to await one loader inside another to fetch dependent data. Loaders must be awaited to ensure they are only executed once. ```ts import 'unplugin-vue-router/client' import './typed-router.d' import { defineBasicLoader as defineLoader } from 'unplugin-vue-router/data-loaders/basic' // ---cut--- // import the loader for user information import { useUserData } from './loaders/users' import { getCommonFriends, getCurrentUser } from './api' export const useUserCommonFriends = defineLoader(async (route) => { // loaders must be awaited inside other loaders // . โคต const user = await useUserData() // magically works const me = await getCurrentUser() // fetch other data const commonFriends = await getCommonFriends(me.id, user.id) return { ...user, commonFriends } }) ``` -------------------------------- ### Vue Component for Home Page Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/introduction.md A simple Vue component to serve as the home page. Ensure this file is placed in the `src/pages` directory to be recognized by the file-based routing. ```vue ``` -------------------------------- ### Define Lazy Data Loader with Basic Options Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/defining-loaders.md Use `defineBasicLoader` with `lazy: true` to prevent data fetching from blocking navigation. The `isLoading` and `error` properties can be used to manage the UI state. ```vue ``` -------------------------------- ### Configure esbuild for unplugin-vue-router Source: https://github.com/posva/unplugin-vue-router/blob/main/README.md Add the plugin to the esbuild configuration. ```ts // esbuild.config.js import { build } from 'esbuild' import VueRouter from 'unplugin-vue-router/esbuild' build({ plugins: [VueRouter()], }) ``` -------------------------------- ### Optional Repeatable Route Parameters Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Combine optional and repeatable parameter syntax (e.g., [[slugs]]+) for optional repeatable parameters. ```js src/pages/articles/[[slugs]]+.vue ``` -------------------------------- ### Define and Export a Basic Data Loader Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/index.md Define a data loader using `defineBasicLoader` within a page component and export it. This loader will be automatically executed when the route changes, fetching data before navigation completes. The composable returned by `defineBasicLoader` can be reused across components to share data fetching instances. ```vue ``` -------------------------------- ### View Generated Route Configuration Source: https://context7.com/posva/unplugin-vue-router/llms.txt The equivalent route object structure generated by the plugin. ```typescript // Generated routes equivalent: const routes = [ { path: '/', component: () => import('src/pages/index.vue') }, { path: '/about', component: () => import('src/pages/about.vue') }, { path: '/users', component: () => import('src/pages/users.vue'), children: [ { path: '', component: () => import('src/pages/users/index.vue') }, { path: ':id', component: () => import('src/pages/users/[id].vue') }, ], }, { path: '/posts/:slug', component: () => import('src/pages/posts/[slug].vue') }, { path: '/posts/:category?', component: () => import('src/pages/posts/[[category]].vue') }, { path: '/articles/:slugs+', component: () => import('src/pages/articles/[slugs]+.vue') }, { path: '/docs/:path*', component: () => import('src/pages/docs/[[...path]].vue') }, { path: '/:path(.*)', component: () => import('src/pages/[...path].vue') }, ] ``` -------------------------------- ### Vue Query Target API Source: https://github.com/posva/unplugin-vue-router/blob/main/src/data-loaders/defineLoader-notes.md Shows how to use `defineQueryLoader` with Vue Query for defining data fetching loaders. Options can be combined with Vue Query options. The `key` can be a string or a function. ```vue ``` -------------------------------- ### Define and export loaders for reuse Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Demonstrates defining a loader in a separate file and exporting it from a page component for use in other components. ```ts // src/loaders/user.ts export const useUserData = defineLoader(...) ``` ```vue ``` ```vue ``` -------------------------------- ### Define Basic Loader with TypeScript Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Use `defineBasicLoader` to define a data loader with automatic type generation for route parameters and return values. Ensure `unplugin-vue-router/client` and `./typed-router.d` are imported for type safety. ```vue ``` -------------------------------- ### Configure tsconfig.json for generated types Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/introduction.md Include the generated typed-router.d.ts file and set moduleResolution to 'Bundler' in your tsconfig.json. ```json { "include": [ // other files... "./typed-router.d.ts" // [!code ++] ], "compilerOptions": { // ... "moduleResolution": "Bundler", // ... } } ``` -------------------------------- ### Add Runtime Routes with HMR Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/hmr.md Use a callback within handleHotUpdate to ensure dynamically added routes persist during development. ```ts import { createRouter, createWebHistory } from 'vue-router' import { routes, handleHotUpdate } from 'vue-router/auto-routes' export const router = createRouter({ history: createWebHistory(), routes, }) function addRedirects() { router.addRoute({ path: '/new-about', redirect: '/about?from=/new-about', }) } if (import.meta.hot) { handleHotUpdate(router, (newRoutes) => { addRedirects() }) } else { // production addRedirects() } ``` -------------------------------- ### Vue Apollo Loader Source: https://github.com/posva/unplugin-vue-router/blob/main/src/data-loaders/defineLoader-notes.md Illustrates defining a loader for Vue Apollo. The key can often be inferred automatically. For dynamic variables based on the route, a function can be passed. ```typescript const useTodos = defineQueryLoader(fetchTodoList, { // the key seems to be inferred automatically }) ``` ```typescript const useContact = defineQueryLoader(fetchContact, (to) => { id: to.params.id }) ``` -------------------------------- ### Configure nuxt.config.ts for Volar Plugin Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/typescript.md If not enabled by default in Nuxt, manually add the `sfc-typed-router` plugin to your `nuxt.config.ts` file within the `typescript.tsConfig.vueCompilerOptions.plugins` array. ```typescript export default defineNuxtConfig({ // ... typescript: { tsConfig: { vueCompilerOptions: { plugins: ['unplugin-vue-router/volar/sfc-typed-router'], }, }, }, }) ``` -------------------------------- ### Manual Loader Connection Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/defining-loaders.md Explicitly associate a loader with a route by adding it to the meta.loaders array in the route configuration. ```ts import { createRouter, createWebHistory } from 'vue-router' import Settings, { useSettings } from './settings.vue' export const router = createRouter({ history: createWebHistory(), routes: [ { path: '/settings', component: Settings, meta: { loaders: [useSettings], }, } ], }) ``` ```vue ``` -------------------------------- ### Control navigation with NavigationResult Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Demonstrates using NavigationResult within a loader to handle redirects or errors during navigation. ```ts import { NavigationResult } from 'vue-router' export const useUserData = defineLoader( async (to) => { try { const user = await getUserById(to.params.id) return user } catch (error) { if (error.status === 404) { return new NavigationResult({ name: 'not-found', params: { pathMatch: '' } } ) } else { throw error // aborts the vue router navigation } } } ) ``` -------------------------------- ### Configure tsconfig.json for Volar Plugin Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/typescript.md Add this configuration to your `tsconfig.json` to enable the `sfc-typed-router` Volar plugin. Ensure `rootDir` is set to `.` for correct path resolution. ```json { "compilerOptions": { "rootDir": "." // ... }, // ... "vueCompilerOptions": { "plugins": ["unplugin-vue-router/volar/sfc-typed-router"] } } ``` -------------------------------- ### Optional Route Parameters Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Use an extra pair of brackets (e.g., [[id]]) to define optional route parameters. ```js src/pages/users/[[id]].vue ``` -------------------------------- ### Configure Auto Imports for Vue Router Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/introduction.md Update `unplugin-auto-import` configuration to use the Vue Router presets exported by `unplugin-vue-router` instead of the default `vue-router` preset. ```ts import { defineConfig } from 'vite' import AutoImport from 'unplugin-auto-import/vite' import { VueRouterAutoImports } from 'unplugin-vue-router' // [!code ++] export default defineConfig({ plugins: [ // other plugins AutoImport({ imports: [ 'vue-router', // [!code --] VueRouterAutoImports, // [!code ++] ], }), ], }) ``` -------------------------------- ### Configure vue.config.js for unplugin-vue-router Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/introduction.md Integrate the unplugin-vue-router/webpack plugin within the configureWebpack section of vue.config.js. ```javascript module.exports = { configureWebpack: { plugins: [ require('unplugin-vue-router/webpack')({ /* options */ }), ], }, } ``` -------------------------------- ### Configure ESLint for vue-router/auto-routes Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/eslint.md Add this to your ESLint configuration if you are not using auto imports to inform ESLint about vue-router/auto-routes. ```json { "settings": { "import/core-modules": ["vue-router/auto-routes"] } } ``` -------------------------------- ### Define a Pinia Colada Loader Source: https://context7.com/posva/unplugin-vue-router/llms.txt Uses defineColadaLoader to implement data fetching with built-in caching, deduplication, and stale-time management. ```vue ``` -------------------------------- ### Immediate Data Commit with `commit: 'immediate'` Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/defining-loaders.md Set `commit: 'immediate'` to update data as soon as it's available, even if other loaders are still pending. This is useful for displaying data without waiting for all fetches to complete. ```typescript import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic' interface Book { title: string isbn: string description: string } function fetchBookCollection(): Promise { return {} as any } // ---cut--- export const useBookCollection = defineBasicLoader(fetchBookCollection, { commit: 'immediate', }) ``` -------------------------------- ### Runtime Route Extension (Admin) Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/extending-routes.md Modify the `routes` array directly before creating the router instance to extend routes at runtime. This is useful for dynamically setting properties like `requiresAuth` for specific routes. ```javascript import { createWebHistory, createRouter } from 'vue-router' import { routes } from 'vue-router/auto-routes' for (const route of routes) { if (route.name === '/admin') { route.meta ??= {} route.meta.requiresAuth = true } } const router = createRouter({ history: createWebHistory(), routes, }) ``` -------------------------------- ### Custom File Extensions for Routes Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Specify custom file extensions (e.g., '.md') to be recognized as route files. This can be set globally or overridden per route folder. ```ts import VueRouter from 'unplugin-vue-router/vite' // --- // @moduleResolution: bundler VueRouter({ // globally set the extensions extensions: ['.vue', '.md'], routesFolder: [ 'src/pages', { src: 'src/docs', // override the global extensions to **only** accept markdown files extensions: ['.md'], }, ], }) ``` -------------------------------- ### Enable Typed Pages in Nuxt Config Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/nuxt/getting-started.md Add this configuration to your `nuxt.config.ts` file to enable experimental typed pages. This setting is required for the plugin to function correctly within Nuxt. ```typescript export default defineNuxtConfig({ experimental: { typedPages: true, }, }) ``` -------------------------------- ### Define a Basic Data Loader Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/data-loaders/rfc.md Defines a data loader for a specific route, allowing data fetching based solely on the URL. It accepts a route type and an async function to fetch data using route parameters. ```typescript import 'unplugin-vue-router/client' import './typed-router.d' import { defineBasicLoader as defineLoader } from 'unplugin-vue-router/data-loaders/basic' // ---cut--- import { getUserById } from '../api' export const useUserData = defineLoader('/users/[id]', async (route) => { return getUserById(route.params.id) }) ``` -------------------------------- ### In-Component Routing with definePage Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/extending-routes.md Use the `definePage()` macro within Vue components to modify route configurations like aliases and meta information. Variables cannot be used directly as parameters. ```vue ``` -------------------------------- ### Repeatable Route Parameters Source: https://github.com/posva/unplugin-vue-router/blob/main/docs/guide/file-based-routing.md Append a plus character (+) after the closing bracket (e.g., [slugs]+) to define repeatable route parameters. ```js src/pages/articles/[slugs]+.vue ``` -------------------------------- ### Configure Vue CLI for unplugin-vue-router Source: https://github.com/posva/unplugin-vue-router/blob/main/README.md Add the plugin to the Vue CLI configuration via configureWebpack. ```js // vue.config.js module.exports = { configureWebpack: { plugins: [ require('unplugin-vue-router/webpack')({ /* options */ }), ], }, } ```