Registering Vue-Router Routes in a Plugin With Vue 3

Last updated 5th September, 2023

The traditional way to register routes in a Vue app is to import them into the app index file and pass them straight to the router to apply them. There are however, cases where this might not work for certain use cases.

Maybe you only want to register certain sub-routes when a user has permission, or you have multiple applications using the same routes. In these cases, you want to be able to configure which routes are registered.

Creating A Plugin To Register Routes

In its simplest form we can create a basic plugin that registers imported routes.

import {
  base,
  pageOne,
  pageTwo,
  pageThree
} from './routes';

export default {
  install(app, options) {
    // The router is injected to the plugin via the options
    // passed to the plugin.
    const {router} = options;

    // First we register the base route of the plugin
    router.addRoute(base);

    // Then we individually register the desired routes.
    // the first parameter is the *name* of the parent
    // you want to attach the new route to. If you leave
    // this out, the route will be registered as a top 
    // level route
    router.addRoute('parent-route', pageOne);
    router.addRoute('parent-route', pageTwo);
    router.addRoute('parent-route', pageThree);
  },
};

With the above plugin code, all we then have to do in our main.js file is use the plugin to register these routes.

import {createApp} from 'vue';
import {createRouter} from 'vue-router';
import App from './App.vue';
import {plugin} from './plugins';

const router = createRouter();

createApp(App)
  // We make sure to register the route first so that when
  // we pass it through to the plugin, it is already setup
  // for adding new routes
  .use(router)
  // Inject the router object into the plugin
  .use(plugin, {router});

Simple. But this isn't doing anything special just yet. You could have just registered routes in the traditional way.

Dynamically Register Routes To A Plugin

The above example is valid, but maybe a little contrived as it doesn't provide us with any new functionality over just importing and registering routes in main.js.

As a better example, say that we use this plugin between multiple applications, and these applications require different routes based on the desired functionality.

In this case, what we can do is pass both the router object and the routes we want to register into the plugin options. This allows us to decide what routes we want each time the the plugin is installed.

import {base} from './routes';

export default {
  install(app, options) {
    // Accept an array of routes that can be registered along
    // with the plugin
    const {router, routes} = options;

    router.addRoute(base);

    // Loop over each of the provided routes and register them
    // using the *base* route as the parent
    routes.forEach((route) => {
      router.addRoute('base', route);
    });
  },
};

First we can add a routes parameter to the plugin options that allows the consumer to pass through the routes they want to register.

import {createApp} from 'vue';
import {createRouter} from 'vue-router';
import App from './App.vue';
import {plugin, pageOne, pageThree} from './plugins';

const router = createRouter();

createApp(App)
  .use(router)
  .use(plugin, {
    router,
    // Inject the routes we want to register with the plugin
    // and omit the ones we don't want
    [
      pageOne,
      pageThree
    ]
  });

Next we pass through only the routes we want in the installation of the plugin. Giving the consumer full control over what routes are registered along with the plugin. 🎉

Conclusion

This is just a couple of potential use cases for registering routes dynamically in plugins, but hopefully it conveys the power of using plugins in Vue to interact with other elements like the router.

One of my favourite use-cases for a system like this is feature flags. Say you fetch some data from an API on load. You could, in that data include which features the user has access to. Using that in combination with the pattern above, you could make sure you're only registering routes that your user can use.

Hope this helped ✌️

No comments yet…

DevInTheWild.

Login To Add Comments.

Want More Like This?

Subscribe to occasional updates.