Automatic injection of Vue router routes
Tags: vue, vuerouter, autoinject
Published: 2021-11-10 06:36:55

Have you ever had your Vue router file get so big that it started getting messy to maintain?  

How about if you had a separate JS file for each route that can be organized into folders and sub folders. And these files are auto injected into the Vue router.

Create a folder in your `/src` directory called `/router` and inside it create an `index.js` file and `/routes` directory

![Image of the router directory containing index.js and routes directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0kww4ybxa9fcxaywjikp.png)

Inside the `routes` directory start creating files for each route you have in your app. You could also create these file in subdirectories inside the `routes` directory.

![Routes directory with route files](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e62h5gzdbjn41qzv17rq.png)
 
Each file should have the below structure.

```js
//this lazy loads the component
const ViewComponent = () => import("@/views/ViewOne");

export default {
	path: "/view-one",
	name: "View One",
	component: ViewComponent,
	show_in_menu: false,
	meta: {
		search: {
			enabled: false,
		},
	},
};

```
As you can see each file would have the normal attributes you would normally find in a vue router config array.

Loading the view component is using an arrow function, the only difference is that using an arrow function lazy loads the component instead of loading it directly.

You might also find additional attributes, e.g:`show_in_menu`, `search` object in the meta.

I use these to auto configure routes based on these configurations. The `show_in_menu` value, if true, will inject this route into the side navigation menu. For the search, if enabled, it will show a search bar in the Toolbar. 

Now once you add all your routes in different files, you need to update the `index.js` we previously created to the following:

```js
import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

//automatically load all files from ./routes directory and register them
const autoLoadedFiles = require.context(
	"./routes", // Look for files in the current directory
	true, // include subdirectories
	/\.js$/ // Only include files that end with .js
);

const routes = [];
//loop over the files in the ./routes directory
autoLoadedFiles.keys().forEach((fileName) => {
	//get the default exported object from the route file and push it to the routes array
	routes.push(autoLoadedFiles(fileName).default);
});

const router = new VueRouter({
	base: '/base-url,
	routes,
});

export default router;
```

And finally you need to import this file in your `main.js` or `app.js` file

```js
import router from "./router";
```

#BONUS:
To retrieve the `show_in_menu` attribute you can loop over the routes as follows:

```js
this.$router.options.routes.forEach((route) => {
    if (route.show_in_menu) {
	    navItems.push(this.createNavItem(route));			 
    }
});
```

To retrieve the meta object you can do so as follows:
```js
this.$router.currentRoute.meta
```

Let me know what do you think of this solution in the comments and if this is something you might use in your projects.

Cheers!