Home > Software design >  Dynamic route with static part possible in vite-plugin-pages?
Dynamic route with static part possible in vite-plugin-pages?

Time:02-02

I'm building a Vue.js 3 app with Vite and vite-plugin-pages for the routing. https://github.com/hannoeru/vite-plugin-pages

Is it possible to have a dynamic route with a static part to it?

e.g. /@[handle].vue

When I do this, it doesn't work and instead falls back to my catch-all route [...all].vue

I don't want to put it in a sub-folder, so /@/[handle].vue is not an option. I'd like the @ symbol followed by whatever comes after being a dynamic username.

I managed to do this in another application using Vue router but not sure how to achieve the same thing in folder-based routing via this plugin.

How I did this before:

const router = new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home,
      children: [
        {
          path: '/@:handle',
          name: 'Profile',
          component: () => import('../views/Profile.vue'),
          props: true,
        },
      ],
    },
  ]
})

CodePudding user response:

You could use the plugin's onRoutesGenerated hook to transform the routes before they're passed to Vue Router.

The solution requires naming the dynamic route parameters with the @ prefix, so the filename in your case would be [@handle].vue:

pages/user/[@handle].vue

The following Vite config renames route parameters that start with @, so that the @ is moved into the path right before the parameter:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Pages({
      onRoutesGenerated(routes) {
        const transformRoute = route => ({
          ...route,
          path: route.path.replace('/:@', '/@:'),
          children: route.children?.map(transformRoute) ?? [],
        })

        return routes.map(transformRoute)
      },
    }),
  ],
})

So the route path for the example above is transformed from this:

/user/:@handle.vue

...to this:

/user/@:handle.vue
                 
  •  Tags:  
  • Related