Search code examples
javascriptvue.jsvuejs2vuexvue-router

Load dynamic Vue routes from json file


Context:

I am building a Vue SPA where I set most of my content in a json file during the build of the application (different content can be served based on environment variables). I need my vue router to be set with some content from that json file!

The problem I am having is that the route is already set before the json content is available. I have read many related solutions, but cannot get anything to work...


Code:

Completely stripped version of my code to understand my current setup:

My main application file app.js:

Vue.use(VueRouter);

new Vue({
  el: '#app',
  store,
  router,
  methods: {
    async storeStaticContent() {
      // This is where I fetch the content and write it away in the store.
      const response = await fetch(`/static/content.json`);
      const json = await response.json();
      this.$store.commit(MUTATIONS.SET_CONTENT, json);
    },
  },
  created() {
    this.storeStaticContent();
  },
});


My router setup router.js:

export const router = new VueRouter({
  mode: 'history',
  routes: [
    {
      // The route I need to populate with a string that I write away to the store in my app.js
      {
        path: `/${store.getters.mainEntity}`,
        name: store.getters.mainEntity,
        component: EntityPage,
      },
      {
        path: '/*',
        name: 'not found',
        component: NotFound,
      },
    }
  ],
  base: '/',
  fallback: true,
});

Two lines from package.json for the versions I am using:

"vue": "^2.6.10",
"vue-router": "^3.1.3",

Solution

  • My prefered way to do this is to download your JSON first, than create a router and after that you can create main Vue instance passing the router instance in...

    Note: I'm leaving out the Vuex stuff for simplicity...

    router.js

    export async createRouter() {
        const response = await fetch(`/static/content.json`)
        const json = await response.json();
        const routes = ...generate routes here from the json object
        return new VueRouter({
          routes,
          // other options
        })
    }
    

    main.js

    import createRouter from `router`
    
    Vue.use(VueRouter);
    
    createRouter().then((router) => {
      new Vue({
        el: '#app',
        store,
        router
      });
    })