Organize your routes with Vue Router
Everyone has its own view on how to organize the routes in a Single-Page Application-we’re not different.
Since we’re using Vue.js in our current project, we’re also using the Vue Router.
Here I would like to describe the approach we took to organize our router and its routes. We will probably change/improve the current state later on but for now I will describe the status quo.
Folder structure
We made a couple of iterations on how we want to organize our routes and we will definitely run through a couple of more iterations until we’re fully satisfied.
Current folder structure we use is pretty straightforward:
index.js
- defines thebeforeEach
logic for the routes/routes/public.js
— holds all the public routes (e.g. /, /login, /registration etc.)/routes/private.js
— has all the routes for the authenticated user/routes/index.js
- just concatenates all the public and private routes and exports them
Let’s walk quickly through every file — you’ll see it will all make sense very quickly.
src/router/index.js
index.js
only holds one root route (you can also go without it). In our case it’s the dashboard route, the user is redirected to once authenticated.
Ok, so the most important part of the index.js
is the beforeEach
check.
In our application we have two types of routes:
the strictly public ones — you have to be logged out to visit them
the private ones - you have to be authenticated to visit them
1 | import Vue from 'vue' |
As you can see from the code snippet above, we read the authentication state from the local Vuex store. Other information that we need to decide whether a route can be visited or not is stored in the meta field of the routes:
onlyLoggedOut
— a route can only be visited by a non authenticated userisPublic
- it’s a public route and can be visited without authentication (/login
,/registration
etc.)
There are only two cases (we’d like to keep it simple in the beginning):
!isPublic && !authenticated
— the user is not authenticated but is trying to access the private route — he/she’ll be redirected to the/login
page and will be redirected to the page he was trying to access upon successful authenticationauthenticated && onlyLoggedOut
- the user is authenticated but is trying to access the public page — he’ll be redirected back to the dashboard
src/router/routes/public.js
We were thinking about breaking down the routes and put every one of them into its own file, but, mmm-maybe later :).
Ok, so all the public routes are in one file and all of them rock the same meta field:
1 | meta: { |
1 | import Login from '@/views/Login.vue' |
In order to not pollute every route, we’re adding the meta field to all the routes in the file in the export section. This way we don’t have to think about adding the meta field to every new added route.
src/router/routes/private.js
You know the drill by now. All the private routes reside in one file and the meta field is added to each and one of them in the export section.
1 | import Accounts from '@/views/Accounts/Index.vue' |
src/router/routes/index.js
What’s inside of the routes/index.js
you may ask. It’s just the utility file that imports the routes from both public.js
and private.js
and exports them as one.
1 | import publicRoutes from '@/router/routes/public.js' |
This file is not necessary, you could just import public and private routes directly into the src/router/index.js
That’s all folks!