Dynamically load Vue routes using a JSON file

Scenario:

In the process of developing a Vue SPA, I have opted to store most of my content in a json file during the application build (with the ability to serve different content based on environment variables). Now, the challenge is integrating this json file data into my vue router!

The issue at hand is that the route gets defined before the json content becomes available. Despite going through various suggested solutions, I haven't been able to make any of them work...


Snippet:

Here's a stripped-down excerpt of my code to provide insight into my current configuration:

Starting with my main application file app.js:

Vue.use(VueRouter);

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


Next up is my router setup in router.js:

export const router = new VueRouter({
  mode: 'history',
  routes: [
    {
        path: `/${store.getters.mainEntity}`,
        name: store.getters.mainEntity,
        component: EntityPage,
      },
      {
        path: '/*',
        name: 'not found',
        component: NotFound,
      },
    }
  ],
  base: '/',
  fallback: true,
});

Lastly, two relevant lines from package.json indicating the versions being used:

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

Answer №1

One method I find effective is to initially download the JSON file and then proceed to create a router. Following that, you can establish the main Vue instance by passing in the router instance...

Note: For simplicity's sake, I am excluding Vuex related details...

router.js

export async function 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
  });
})

Answer №2

If you're searching for the addRoutes method:

Check out router.addRoutes in the Vue Router API

Assuming everything is set up correctly in your store, this should work:

  methods: {
    async fetchAndStoreContent() {
      // Fetch content and save it in the store
      const response = await fetch(`/static/content.json`);
      const data = await response.json();
      this.$store.commit(MUTATIONS.SET_CONTENT, data);
      this.addNewRoute();
    },
    addNewRoute: function() {
      this.$router.addRoutes(
        [{
          path: `/${store.getters.mainEntity}`,
          name: store.getters.mainEntity,
          component: EntityPage,
        }]
      );
    }
  },

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Expanding upon React Abstract Component using Typescript

Currently, I am in the process of building a library that contains presentations using React. To ensure consistency and structure, each presentation component needs to have specific attributes set. This led me to create a TypeScript file that can be extend ...

Refresh the webpage source code for an AJAX request

When using AJAX calls on a page, I have noticed that the page source remains unchanged. This can be problematic if a user performs forward/backward operations in their browser, as the browser will display the original HTML code instead of the updated conte ...

Unexpected error occurs when modifying HTML5 video source using JQuery on Internet Explorer

Currently, I am working on developing a web application using asp.net, Bootstrap, and JQuery. While testing it on LocalHost, I encountered an issue that needs debugging. The navigation bar of my application has a dropdown menu with links to tutorial video ...

What is the method to display just the final 3 characters within a paragraph?

Is there a way to display only the last three characters of a string using either a method or a string method? I consistently have a 13-digit number, but I specifically require showing only the final three digits. Appreciate any assistance provided. Than ...

Exploring the use of jQuery autocomplete to retrieve data attributes

Looking to retrieve additional data-attributes from the Mapbox API. The autocomplete plugin I implemented can be found here. (Utilizing Python/Django for backend) My goal is to send extra information such as country code, city, and country to my databas ...

Ways to set values for attributes

I am seeking guidance on how to set values for the properties foo and greetingMessage App.vue: <template> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> < ...

Tips on managing a GET request sent using axios with special characters and accents

When constructing a web page using VUE.JS, a GET request is made with Axios. In the form fields, special characters and accents may be present depending on the user's input. For instance, if the surname entered in the form field is 'Ruíz' ...

Issue with JavaScript not generating a header element within a specified div

function searchingFunction() { var searchInput = document.getElementById("searchbar"); if (searchInput.value != null) { var resultElement = document.createElement("h2"); resultElement.innerHTML = "Search results for " + searchInput.value; d ...

Using JavaScript's `Map` function instead of a traditional `for`

My dataset consists of a csv file containing 5000 rows, with each row having thirty fields representing measurements of different chemical elements. I aim to parse and visualize this data using D3js. Upon reading the file, I obtain an array of length 5000 ...

What is the best way to add multiple rows using a parameter in SQL?

My goal is to insert multiple rows in SQLite using the ionic framework. Inserting a single row works fine, as does running the following query: INSERT INTO categories (category_id, category_name, category_type) VALUES (1,"test",1),(2,"test again", 2); ...

What could be causing the issue with setting a value for a JSON array in the following method?

Consider this piece of code that I'm currently working with: compareList[productName] = productID + ',' + productHref; console.log(productName + ' ' + productID + ' ' + productHref + ' ' + compareList.length); ...

What is the best way to generate the message dynamically?

I have implemented the react-intl package for translation purposes in my project. Users have the option to choose between Spanish and English languages, with Spanish being the default language. When a user switches to English, all text should be dynamicall ...

When a user clicks on a child element in ReactJS, the onclick event returns as undefined

I am experiencing an issue with my restaurants list component. While I have an onClick event set up for each list item, clicking on a child element of the list item does not trigger the expected response. When this occurs, nothing happens or I see an undef ...

Is Your CanvasJS Chart Traveling in Reverse?

My charts are displaying dates in reverse order, can anyone help me figure out what's causing this issue? I've checked the documentation but couldn't find anything that would explain this problem. Link to documentation: Here is a screensh ...

Rendering text with three.js in the scene

I'm just starting out with three.js. For my project, I need to create a 3D graphical website. After doing some research on Google, I discovered that three.js is a great tool for manipulating WebGL with ease. In the three.js documentation(), TextGe ...

What is the equivalent of getElementById in .ts when working with tags in .js?

Looking to incorporate Electron, Preload, Renderer with ReactJS and TypeScript into my project. <index.html> <body> <div id="root" /> <script src='./renderer.js'/> </body> <index.ts> const root = Re ...

What causes the maximum update depth exceeded error in React when trying to set data to the context?

When building my React project, I implemented a context to share the selected currency across components. While the context functionality is working well, I encountered a small issue regarding setting a default currency. At the start of the web applicati ...

What is the process for importing the TokenExpiredError that is thrown by the verify function in jsonwebtoken?

Is there a way to determine if an Error object thrown by the jwt.verify function in the jsonwebtoken library is of type TokenExpiredError using Typescript's instanceof? For example: import jwt from "jsonwebtoken"; function someFunction() { try { ...

centered shape-outside within a div

I'm looking to create a layout with paragraphs displayed in columns, with a middle paragraph centered within the parent div. The text of the paragraphs should wrap around the middle paragraph with some margin. Check out the reference photo Below is ...

An effective way to incorporate internal scripts into a view within the Play Framework

Is there a preferred method for including internal JavaScript code in a Play Framework view using script tags? ...