### Basic App Setup for Nested Routes Source: https://router.vuejs.org/guide/essentials/nested-routes Initial setup for a top-level router view and a parent User component. ```vue ``` ```vue ``` ```js import User from './User.vue' // these are passed to `createRouter` const routes = [{ path: '/user/:id', component: User }] ``` -------------------------------- ### SSR history setup with createMemoryHistory Source: https://router.vuejs.org/guide/migration/index.html On SSR, manually pass the appropriate history: `createMemoryHistory()` on the server and `createWebHistory()` on the client. Then push the request URL and wait for `router.isReady()`. ```javascript // router.js let history = isServer ? createMemoryHistory() : createWebHistory() let router = createRouter({ routes, history }) // somewhere in your server-entry.js router.push(req.url) // request url router.isReady().then(() => { // resolve the request }) ``` -------------------------------- ### Define routes with nested children for active link example Source: https://router.vuejs.org/guide/essentials/active-links.html Example route configuration with a parent route `/user/:username` and a child route `role/:roleId`. Used to illustrate how ancestor routes are considered active when params match. ```javascript const routes = [ { path: '/user/:username', component: User, children: [ { path: 'role/:roleId', component: Role, }, ], }, ] ``` -------------------------------- ### Use named route in to prop Source: https://router.vuejs.org/guide/essentials/named-routes Pass an object with `name` and `params` to the `to` prop to navigate to the named route. The example creates a link to `/user/erina`. ```HTML User profile ``` -------------------------------- ### Route configuration with component User Source: https://router.vuejs.org/guide/essentials/passing-props Route configuration that maps `/users/:id` to the User component. This is used with the initial `$route` example. ```js import User from './User.vue' // these are passed to `createRouter` const routes = [{ path: '/users/:id', component: User }] ``` -------------------------------- ### Named views with props option Source: https://router.vuejs.org/guide/essentials/passing-props For routes with named views, define the `props` option for each named view. Here, `default` gets `true` and `sidebar` gets `false`. ```js const routes = [ { path: '/user/:id', components: { default: User, sidebar: Sidebar }, props: { default: true, sidebar: false }, }, ] ``` -------------------------------- ### Accessing Router and Route with useRouter and useRoute Source: https://router.vuejs.org/guide/advanced/composition-api Use `useRouter` and `useRoute` inside `setup` to access the router and current route. The `route` object is reactive; avoid watching the whole object and instead watch specific properties. ```vue ``` -------------------------------- ### RouterLink examples for active and exact active classes Source: https://router.vuejs.org/guide/essentials/active-links.html Two RouterLink components: one to `/user/erina` and one to `/user/erina/role/admin`. When the current path is `/user/erina/role/admin`, both get `router-link-active`, but only the second gets `router-link-exact-active`. ```html User Role ``` -------------------------------- ### IIS web.config for History Mode Source: https://router.vuejs.org/guide/essentials/history-mode IIS configuration using UrlRewrite to rewrite all requests to the root, enabling history mode. Requires installing IIS UrlRewrite. ```xml ``` -------------------------------- ### Define nested route with children array Source: https://router.vuejs.org/guide/advanced/dynamic-routing Equivalent to the previous example, defining the nested route directly in the children array. ```javascript router.addRoute({ name: 'admin', path: '/admin', component: Admin, children: [{ path: 'settings', component: AdminSettings }], }) ``` -------------------------------- ### User.vue template using $route.params.id Source: https://router.vuejs.org/guide/essentials/passing-props Initial component that directly uses `$route.params.id`, creating a tight coupling with the route. This is the starting point before refactoring to use props. ```vue ``` -------------------------------- ### Watching Route Params with useRoute Source: https://router.vuejs.org/guide/advanced/composition-api Watch a specific route property (e.g., `route.params.id`) to react to changes. This example fetches user data when the id param changes. ```vue ``` -------------------------------- ### Incorrect usage of the next argument Source: https://router.vuejs.org/guide/advanced/navigation-guards A bad example showing how calling next multiple times in overlapping logical paths can cause errors. ```javascript // BAD router.beforeEach((to, from, next) => { if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' }) // if the user is not authenticated, `next` is called twice next() }) ``` -------------------------------- ### Access to and from properties on navigation failure Source: https://router.vuejs.org/guide/advanced/navigation-failures Shows that navigation failures expose to and from properties reflecting the target and current locations. The example checks for an aborted navigation when trying to access /admin. ```js // trying to access the admin page router.push('/admin').then(failure => { if (isNavigationFailure(failure, NavigationFailureType.aborted)) { failure.to.path // '/admin' failure.from.path // '/' } }) ``` -------------------------------- ### Access router and route with Composition API composables Source: https://router.vuejs.org/guide Uses useRouter() and useRoute() composables to access the router instance and current route. The example shows a computed property that reads and updates the query parameter 'search'. ```vue ``` -------------------------------- ### Complex function returning a Promise for route component Source: https://router.vuejs.org/guide/advanced/lazy-loading.html Shows that the component option can accept any function that returns a Promise, not just dynamic imports. This example returns a Promise resolving to a component definition. ```javascript const UserDetails = () => Promise.resolve({/* component definition */}) ``` -------------------------------- ### Import unplugin plugin for webpack, rollup, esbuild Source: https://router.vuejs.org/guide/migration/v4-to-v5.html For other build tools (Webpack, Rollup, esbuild), import the plugin from 'vue-router/unplugin' and use the corresponding methods. The example shows usage of `VueRouter.webpack` and `VueRouter.rollup`. ```ts import VueRouter from 'vue-router/unplugin' VueRouter.webpack({/* ... */}) VueRouter.rollup({/* ... */}) // etc. ``` -------------------------------- ### Configure strict and sensitive route options Source: https://router.vuejs.org/guide/essentials/route-matching-syntax Sets `strict: true` at the router level to apply to all routes, and `sensitive: true` on a specific route to make it case-sensitive. The example shows that `/users/:id` with `sensitive: true` will not match `/Users/posva`, and with `strict: true` will not match `/users/posva/`. ```javascript const router = createRouter({ history: createWebHistory(), routes: [ // will match /users/posva but not: // - /users/posva/ because of strict: true // - /Users/posva because of sensitive: true { path: '/users/:id', sensitive: true }, // will match /users, /Users, and /users/42 but not /users/ or /users/42/ { path: '/users/:id?' }, ], strict: true, // applies to all routes }) ``` -------------------------------- ### useLink Composition API example Source: https://router.vuejs.org/guide/advanced/extending-router-link Render function or computed properties alternative using useLink from the Composition API. It destructures navigate, href, route, isActive, and isExactActive from useLink(props) to build a custom AppLink component. Note that the returned isExternalLink is not defined in the snippet, so it must be computed separately. ```js import { RouterLink, useLink } from 'vue-router' export default { name: 'AppLink', props: { // add @ts-ignore if using TypeScript ...RouterLink.props, inactiveClass: String, }, setup(props) { // `props` contains `to` and any other prop that can be passed to const { navigate, href, route, isActive, isExactActive } = useLink(props) // profit! return { isExternalLink } }, } ``` -------------------------------- ### Register the router plugin with use() Source: https://router.vuejs.org/guide Registers the router instance as a plugin on the app. The call to use() must happen before mount(). Two equivalent forms are shown: chaining and separate statements. ```js createApp(App).use(router).mount('#app') ``` ```js const app = createApp(App) app.use(router) app.mount('#app') ``` -------------------------------- ### Await initial navigation with router.isReady() Source: https://router.vuejs.org/guide/advanced/transitions Await router.isReady() before mounting the app to ensure initial navigation is complete, affecting enter transitions. ```ts const app = createApp(App) app.use(router) // mount after the initial navigation is ready await router.isReady() app.mount('#app') ``` -------------------------------- ### HTML5 Mode with createWebHistory() Source: https://router.vuejs.org/guide/essentials/history-mode Recommended history mode. Requires a server catch-all fallback to serve index.html for direct URL access. ```JavaScript import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), routes: [ //... ], }) ``` -------------------------------- ### Create router with catch-all route Source: https://router.vuejs.org/guide/advanced/dynamic-routing Creates a router with a single catch-all route that matches any path and renders the Article component. ```javascript const router = createRouter({ history: createWebHistory(), routes: [{ path: '/:articleName', component: Article }], }) ``` -------------------------------- ### Update tsconfig.json and Volar plugins Source: https://router.vuejs.org/guide/migration/v4-to-v5.html In tsconfig.json, change the Volar plugins from 'unplugin-vue-router/volar/*' to 'vue-router/volar/*'. The example shows the before and after for the `sfc-typed-router` and `sfc-route-blocks` plugins. ```jsonc // tsconfig.json { "compilerOptions": { "rootDir": ".", }, "vueCompilerOptions": { "plugins": [ "unplugin-vue-router/volar/sfc-typed-router", "unplugin-vue-router/volar/sfc-route-blocks", "vue-router/volar/sfc-typed-router", "vue-router/volar/sfc-route-blocks", ], }, } ``` -------------------------------- ### Update data loader imports Source: https://router.vuejs.org/guide/migration/v4-to-v5.html Replace imports for data loaders from 'unplugin-vue-router/data-loaders/*' to 'vue-router/experimental'. The example shows the before and after for `defineBasicLoader`, `defineColadaLoader`, and `DataLoaderPlugin`. ```ts import { defineBasicLoader } from 'unplugin-vue-router/data-loaders/basic' import { defineColadaLoader } from 'unplugin-vue-router/data-loaders/pinia-colada' import { DataLoaderPlugin } from 'unplugin-vue-router/data-loaders' import { defineBasicLoader, DataLoaderPlugin } from 'vue-router/experimental' import { defineColadaLoader } from 'vue-router/experimental/pinia-colada' ``` -------------------------------- ### Caddy v2 try_files Configuration Source: https://router.vuejs.org/guide/essentials/history-mode Caddy v2 configuration to try the requested path and fallback to the root. ```caddy try_files {path} / ``` -------------------------------- ### Wait for router readiness before mounting app Source: https://router.vuejs.org/guide/migration/index.html Waits for the router to be ready before mounting the app. Necessary because all navigations, including the first one, are now asynchronous. On the server side, you need to manually push the initial location. ```js app.use(router) // Note: on Server Side, you need to manually push the initial location router.isReady().then(() => app.mount('#app')) ``` -------------------------------- ### Get parent route from matched array Source: https://router.vuejs.org/guide/migration/index.html Accesses the parent route from the `matched` array. The `parent` property has been removed from normalized route locations. ```js const parent = this.$route.matched[this.$route.matched.length - 2] ``` -------------------------------- ### Define catch-all and custom regex routes Source: https://router.vuejs.org/guide/essentials/dynamic-matching Use custom regex params to match anything. `/:pathMatch(.*)*` captures the full path under `route.params.pathMatch`, and `/user-:afterUser(.*)` captures anything after `/user-`. ```JavaScript const routes = [ // will match everything and put it under `route.params.pathMatch` { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound }, // will match anything starting with `/user-` and put it under `route.params.afterUser` { path: '/user-:afterUser(.*)', component: UserGeneric }, ] ``` -------------------------------- ### Create a router instance with createRouter() Source: https://router.vuejs.org/guide Defines routes mapping URL paths to components and creates a router with createMemoryHistory(). The history option controls URL mapping; createMemoryHistory() ignores the browser URL, while createWebHistory() or createWebHashHistory() are typical for real apps. ```js import { createMemoryHistory, createRouter } from 'vue-router' import HomeView from './HomeView.vue' import AboutView from './AboutView.vue' const routes = [ { path: '/', component: HomeView }, { path: '/about', component: AboutView }, ] export const router = createRouter({ history: createMemoryHistory(), routes, }) ``` -------------------------------- ### Replace router.onReady with router.isReady Source: https://router.vuejs.org/guide/migration/index.html router.onReady has been replaced with router.isReady(), which returns a Promise. Use .then()/.catch() or await to handle success and error. ```js // replace router.onReady(onSuccess, onError) // with router.isReady().then(onSuccess).catch(onError) // or use await: try { await router.isReady() // onSuccess } catch (err) { // onError } ``` -------------------------------- ### Handling params with path and encoding Source: https://router.vuejs.org/guide/essentials/navigation.html Demonstrates how to manually build URLs with encodeURIComponent when using path, and why using name and params is preferred for automatic encoding. Also shows that params cannot be used alongside path. ```javascript const username = 'eduardo/san martin' // we can manually build the url but we will have to handle the encoding ourselves router.push(`/user/${encodeURIComponent(username)}`) // -> /user/eduardo%2Fsan%20martin // same as router.push({ path: `/user/${encodeURIComponent(username)}` }) // -> /user/eduardo%2Fsan%20martin // if possible use `name` and `params` to benefit from automatic URL encoding router.push({ name: 'user', params: { username } }) // -> /user/eduardo%2Fsan%20martin // `params` cannot be used alongside `path` router.push({ path: '/user', params: { username } }) // -> /user ``` -------------------------------- ### router.push with string path and location descriptor object Source: https://router.vuejs.org/guide/essentials/navigation.html Shows various ways to call router.push: with a literal string path, an object with path, a named route with params, query, and hash. Note that params are ignored if a path is provided, but query is not. ```javascript // literal string path router.push('/users/eduardo') // object with path router.push({ path: '/users/eduardo' }) // named route with params to let the router build the url router.push({ name: 'user', params: { username: 'eduardo' } }) // with query, resulting in /register?plan=private router.push({ path: '/register', query: { plan: 'private' } }) // with hash, resulting in /about#team router.push({ path: '/about', hash: '#team' }) ``` -------------------------------- ### Fast regex example: `.*` at the end without repeatable modifier Source: https://router.vuejs.org/guide/essentials/route-matching-syntax This route definition is fine because the `.*` is at the end and not repeatable. It matches the same routes but without an array of params and is much faster. ```ts const routes = [ // This is fine because the `.*` is at the end { path: '/:pathMatch(.*)/something-at-the-end' }, ] ``` -------------------------------- ### Create router with createRouter Source: https://router.vuejs.org/guide/migration/index.html Replaces the previous `new Router()` class instantiation. Import `createRouter` from 'vue-router' and call it with a configuration object. ```javascript import { createRouter } from 'vue-router' const router = createRouter({ // ... }) ``` -------------------------------- ### Remove old client types reference from tsconfig.json Source: https://router.vuejs.org/guide/migration/v4-to-v5.html Remove `unplugin-vue-router/client` from the `include` array in tsconfig.json. The example shows the old include with `unplugin-vue-router/client` and comments indicate it should be removed. ```jsonc { "include": [ "./typed-router.d.ts", "unplugin-vue-router/client", // ... ], } ``` -------------------------------- ### Use history option with createWebHistory Source: https://router.vuejs.org/guide/migration/index.html Replaces the `mode` option with the `history` option. Use `createWebHistory()` for 'history' mode, `createWebHashHistory()` for 'hash', and `createMemoryHistory()` for 'abstract'. ```javascript import { createRouter, createWebHistory } from 'vue-router' // there is also createWebHashHistory and createMemoryHistory createRouter({ history: createWebHistory(), routes: [], }) ``` -------------------------------- ### Watch route.params.id with Options API Source: https://router.vuejs.org/guide/essentials/dynamic-matching Use `this.$watch` in the `created` hook to react to param changes. This is the Options API equivalent for the Composition API watch example. ```Vue ``` -------------------------------- ### Basic RouterView transition with fade Source: https://router.vuejs.org/guide/advanced/transitions Wrap the component in a inside the slot to apply a fade transition to all routes. ```template ``` -------------------------------- ### Nested named routes with empty path Source: https://router.vuejs.org/guide/migration/index.html Example of nested named routes with an empty path child. Navigating to the 'dashboard' route now produces a URL without a trailing slash. ```javascript const routes = [ { path: '/dashboard', name: 'dashboard-parent', component: DashboardParent, children: [ { path: '', name: 'dashboard', component: DashboardDefault }, { path: 'settings', name: 'dashboard-settings', component: DashboardSettings, }, ], }, ] ``` -------------------------------- ### Scaffold a project with create-vue Source: https://router.vuejs.org/guide Commands to create a new Vue project using the create-vue scaffolding tool, which includes an option to add Vue Router. Shown for npm, yarn, and pnpm package managers. ```bash npm create vue@latest ``` ```bash yarn create vue ``` ```bash pnpm create vue ``` -------------------------------- ### router.push with replace: true and router.replace Source: https://router.vuejs.org/guide/essentials/navigation.html Shows how to replace the current history entry by adding replace: true to the to argument or using router.replace directly. ```javascript router.push({ path: '/home', replace: true }) // equivalent to router.replace({ path: '/home' }) ``` -------------------------------- ### Scroll to element with offset Source: https://router.vuejs.org/guide/advanced/scroll-behavior.html Uses a CSS selector or DOM element via `el` to scroll to an element, with `top` and `left` as relative offsets. Example scrolls 10px above `#main`. ```javascript const router = createRouter({ scrollBehavior(to, from, savedPosition) { // always scroll 10px above the element #main return { // could also be // el: document.getElementById('main'), el: '#main', // 10px above the element top: 10, } }, }) ``` -------------------------------- ### Redirect with path string Source: https://router.vuejs.org/guide/essentials/redirect-and-alias Redirects from '/home' to '/' in the routes configuration. The redirect target is a path string. ```js const routes = [{ path: '/home', redirect: '/' }] ``` -------------------------------- ### Registering a global before guard Source: https://router.vuejs.org/guide/advanced/navigation-guards Use router.beforeEach to register a global guard that can cancel navigation by returning false. ```javascript const router = createRouter({ ... }) router.beforeEach((to, from) => { // ... // explicitly return false to cancel the navigation return false }) ``` -------------------------------- ### Slow regex example: greedy `.*` with repeatable modifier Source: https://router.vuejs.org/guide/essentials/route-matching-syntax This route definition creates a very slow regex because of the greedy `.*` followed by `*` and a static string. Avoid using such patterns as they can lead to serious performance issues. ```ts const routes = [ // This creates a very slow regex because of the greedy `.*` followed by `*` and a static string { path: '/:pathMatch(.*)*/something-at-the-end' }, ] ``` -------------------------------- ### Navigate to a catch-all route with params array Source: https://router.vuejs.org/guide/essentials/dynamic-matching When using a repeatable param like `pathMatch`, you can pass an array of path segments to `router.push`. This preserves the current path, query, and hash. ```JavaScript router.push({ name: 'NotFound', // preserve current path and remove the first char to avoid the target URL starting with `//` params: { pathMatch: route.path.substring(1).split('/') }, // preserve existing query and hash if any query: route.query, hash: route.hash, }) ``` -------------------------------- ### NavLink.vue with Tailwind CSS Source: https://router.vuejs.org/guide/advanced/extending-router-link Example of using the AppLink component with Tailwind CSS classes to create a NavLink.vue component. It passes active-class and inactive-class props to style the link based on its active state. ```vue ``` -------------------------------- ### nginx Location Block for History Mode Source: https://router.vuejs.org/guide/essentials/history-mode nginx configuration to try files and fallback to /index.html for client-side routing. ```nginx location / { try_files $uri $uri/ /index.html; } ``` -------------------------------- ### Alias for a route Source: https://router.vuejs.org/guide/essentials/redirect-and-alias Defines an alias '/home' for the path '/'. When visiting '/home', the URL remains '/home' but the route matches as '/'. Aliases should start with '/' for absolute paths in nested routes. ```js const routes = [{ path: '/', component: Homepage, alias: '/home' }] ``` -------------------------------- ### Pass base option to createWebHistory Source: https://router.vuejs.org/guide/migration/index.html The `base` option is now passed as the first argument to `createWebHistory` (and other history functions). ```javascript import { createRouter, createWebHistory } from 'vue-router' createRouter({ history: createWebHistory('/base-directory/'), routes: [], }) ``` -------------------------------- ### Define optional parameters with ? modifier Source: https://router.vuejs.org/guide/essentials/route-matching-syntax Shows how to mark a parameter as optional using the `?` modifier. The first route matches `/users` and `/users/posva`, while the second matches `/users` and `/users/42` (with a digit constraint). ```javascript const routes = [ // will match /users and /users/posva { path: '/users/:userId?' }, // will match /users and /users/42 { path: '/users/:userId(\\d+)?' }, ] ``` -------------------------------- ### Replace router-link append prop with manual path concatenation Source: https://router.vuejs.org/guide/migration/index.html The append prop has been removed. Manually concatenate the path using a global append function. The example shows the replacement and the required global function. ```template replace to relative child with to relative child ``` ```js app.config.globalProperties.append = (path, pathToAppend) => path + (path.endsWith('/') ? '' : '/') + pathToAppend ``` -------------------------------- ### Define catch-all routes with pathMatch Source: https://router.vuejs.org/guide/migration/index.html Catch-all routes (`*`, `/*`) must now use a parameter with a custom regex. Use `/:pathMatch(.*)*` for repeated params to avoid encoding slashes when resolving named routes. ```javascript const routes = [ // pathMatch is the name of the param, e.g., going to /not/found yields // { params: { pathMatch: ['not', 'found'] }} // this is thanks to the last *, meaning repeated params and it is necessary if you // plan on directly navigating to the not-found route using its name { path: '/:pathMatch(.*)*', name: 'not-found', component: NotFound }, // if you omit the last `*`, the `/` character in params will be encoded when resolving or pushing { path: '/:pathMatch(.*)', name: 'bad-not-found', component: NotFound }, ] // bad example if using named routes: router.resolve({ name: 'bad-not-found', params: { pathMatch: 'not/found' }, }).href // '/not%2Ffound' // good example: router.resolve({ name: 'not-found', params: { pathMatch: ['not', 'found'] }, }).href // '/not/found' ``` -------------------------------- ### Access router with Options API using this.$router Source: https://router.vuejs.org/guide Shows how to access the router instance in a component using the Options API. The method calls push() for programmatic navigation. ```js export default { methods: { goToAbout() { this.$router.push('/about') }, }, } ``` -------------------------------- ### Apache Configuration for History Mode Source: https://router.vuejs.org/guide/essentials/history-mode Apache .htaccess configuration using mod_rewrite to fallback to index.html for history mode. Assumes app is served from root folder; adjust RewriteBase for subfolder deployments. ```apache Options -MultiViews RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.html [L] ``` -------------------------------- ### JavaScript: Route configuration with named components Source: https://router.vuejs.org/guide/essentials/named-views.html Define multiple components for a route using the 'components' option (with an 's'). Each component maps to a named router-view outlet. ```js const router = createRouter({ // ... routes: [ { path: '/', components: { default: Home, // Renders to sidebar: MainSidebar, // Renders to footer: MainToolbar, // Renders to }, }, ], }) ``` -------------------------------- ### AppLink.vue with Composition API Source: https://router.vuejs.org/guide/advanced/extending-router-link Composition API version of the AppLink component. It extends RouterLink to handle external links (those starting with 'http') by rendering a plain anchor with target="_blank", and for internal links it uses the custom v-slot to apply active and inactive classes. The component inherits RouterLink props and adds an inactiveClass prop. ```vue ``` -------------------------------- ### Group components in same chunk with Vite rollupOptions Source: https://router.vuejs.org/guide/advanced/lazy-loading.html Shows how to configure Vite's `rollupOptions.output.manualChunks` to group specific route components into a single chunk named 'group-user', so they load with one request. ```javascript export default defineConfig({ build: { rollupOptions: { // https://rollupjs.org/guide/en/#outputmanualchunks output: { manualChunks: { 'group-user': [ './src/UserDetails', './src/UserDashboard', './src/UserProfileEdit', ], }, }, }, }, }) ``` -------------------------------- ### Fetch Before Navigation with beforeRouteEnter and beforeRouteUpdate Source: https://router.vuejs.org/guide/advanced/data-fetching.html Fetch data before navigation using the `beforeRouteEnter` guard. The callback passed to `next` runs after the component is mounted, allowing access to the component instance via `vm`. Also handles `beforeRouteUpdate` for when the route changes while the component is already rendered. ```js export default { data() { return { post: null, error: null, } }, async beforeRouteEnter(to, from, next) { try { const post = await getPost(to.params.id) // `setPost` is a method defined below next(vm => vm.setPost(post)) } catch (err) { // `setError` is a method defined below next(vm => vm.setError(err)) } }, // when route changes and this component is already rendered, // the logic will be slightly different. beforeRouteUpdate(to, from) { this.post = null getPost(to.params.id).then(this.setPost).catch(this.setError) }, methods: { setPost(post) { this.post = post }, setError(err) { this.error = err.toString() }, }, } ``` -------------------------------- ### Vercel Rewrites Configuration Source: https://router.vuejs.org/guide/essentials/history-mode Vercel configuration in vercel.json to rewrite all paths to /index.html. ```json { "rewrites": [{ "source": "/:path*", "destination": "/index.html" }] } ``` -------------------------------- ### Add route and manually navigate with router.replace() Source: https://router.vuejs.org/guide/advanced/dynamic-routing Adds a route and then manually navigates to the current full path to display the newly added route, avoiding a duplicate history entry. ```javascript router.addRoute({ path: '/about', component: About }) // we could also use this.$route or useRoute() router.replace(router.currentRoute.value.fullPath) ``` -------------------------------- ### Resolve named routes with repeatable params Source: https://router.vuejs.org/guide/essentials/route-matching-syntax Shows how to use named routes with repeatable params. For '*', passing an empty array produces '/', and passing ['a','b'] produces '/a/b'. For '+', passing an empty array throws an Error because the param requires at least one segment. ```js // given { path: '/:chapters*', name: 'chapters' }, router.resolve({ name: 'chapters', params: { chapters: [] } }).href // produces / router.resolve({ name: 'chapters', params: { chapters: ['a', 'b'] } }).href // produces /a/b // given { path: '/:chapters+', name: 'chapters' }, router.resolve({ name: 'chapters', params: { chapters: [] } }).href // throws an Error because `chapters` is empty ``` -------------------------------- ### Navigate history with router.go and silent failure handling Source: https://router.vuejs.org/guide/essentials/navigation.html Use cases for router.go with integers: forward and backward navigation steps like go(1), go(-1), go(3), and large values like -100 or 100 that fail silently if the record count is insufficient. It is the counterpart of window.history.go(n). ```JavaScript // go forward by one record, the same as router.forward() router.go(1) // go back by one record, the same as router.back() router.go(-1) // go forward by 3 records router.go(3) // fails silently if there aren't that many records router.go(-100) router.go(100) ``` -------------------------------- ### Create Router with Memory History Source: https://router.vuejs.org/guide/essentials/history-mode Use createMemoryHistory() to create a router that doesn't interact with the URL and doesn't trigger initial navigation. Requires manually pushing the initial navigation after app.use(router). ```javascript import { createRouter, createMemoryHistory } from 'vue-router' const router = createRouter({ history: createMemoryHistory(), routes: [ //... ], }) ``` -------------------------------- ### Global Injections within Guards (Vue 3.3+) Source: https://router.vuejs.org/guide/advanced/navigation-guards Shows how to use `inject()` inside navigation guards since Vue 3.3. Anything provided with `app.provide()` is accessible within `router.beforeEach()`, `router.beforeResolve()`, and `router.afterEach()`. Useful for injecting global properties like Pinia stores. ```ts const app = createApp(App) app.provide('global', 'hello injections') // router.ts or main.ts router.beforeEach((to, from) => { const global = inject('global') // 'hello injections' // a pinia store const userStore = useAuthStore() // ... }) ``` -------------------------------- ### Await router.push to wait for navigation Source: https://router.vuejs.org/guide/advanced/navigation-failures Shows the difference between not awaiting and awaiting the promise returned by router.push. The first snippet closes the menu immediately because navigations are asynchronous; the second waits for the navigation to finish before closing the menu. ```js router.push('/my-profile') this.isMenuOpen = false ``` ```js await router.push('/my-profile') this.isMenuOpen = false ``` -------------------------------- ### Differentiate routes with static path sections Source: https://router.vuejs.org/guide/essentials/route-matching-syntax Defines two routes that differentiate by a static prefix: '/o/:orderId' matches URLs like /o/3549, and '/p/:productName' matches URLs like /p/books. This is the simplest way to distinguish routes when params alone would collide. ```js const routes = [ // matches /o/3549 { path: '/o/:orderId' }, // matches /p/books { path: '/p/:productName' }, ] ``` -------------------------------- ### Multiple aliases with array Source: https://router.vuejs.org/guide/essentials/redirect-and-alias Provides multiple aliases for a child route. The child route with path '' and alias ['/people', 'list'] renders UserList for /users, /users/list, and /people. Aliases can be absolute or relative. ```js const routes = [ { path: '/users', component: UsersLayout, children: [ // this will render the UserList for these 3 URLs // - /users // - /users/list // - /people { path: '', component: UserList, alias: ['/people', 'list'] }, ], }, ] ``` -------------------------------- ### Function mode for dynamic props Source: https://router.vuejs.org/guide/essentials/passing-props Create a function that returns props, allowing casting parameters to other types or combining static and route-based values. For `/search?q=vue`, it passes `{query: 'vue'}` to `SearchUser`. ```js const routes = [ { path: '/search', component: SearchUser, props: route => ({ query: route.query.q }), }, ] ```