How to retrieve a list of routes using axios in a Vue project set up with Webpack

I have implemented the prerender-spa-plugin in my Vue Webpack Cli project following the documentation by registering the Plugin in webpack.prod.conf.js as shown below:

...
plugins: [
  ...
  new PrerenderSpaPlugin(
    path.join(__dirname, '../dist'),
    ['/', '/about', '/contact'],
    {
      captureAfterTime: 5000
    }
  )
]

Now, I am exploring the possibility of retrieving the list of routes array via an axios call. However, my attempts so far have been unsuccessful as illustrated in the code snippet below:

var routes = axios.get('http://myapi.com/api').then(function (response) {
  return response.map(function (response) {
    return '/base/' + response.slug
  })
})

plugins: [
  ...
  new PrerenderSpaPlugin(
    path.join(__dirname, '../dist'),
    routes,
    {
      captureAfterTime: 5000
    }
  )
]

Due to my limited Javascript knowledge, I am struggling to resolve this issue. Any guidance or insights on how to achieve this would be greatly appreciated.

Best regards

Answer №1

At the moment, this solution may not function properly due to Webpack's default assumption of synchronous configuration. A workaround is to utilize Webpack's ability to handle asynchronous configuration by returning a promise that resolves after your route request.

If you have access to an environment that supports async/await (node 8+), all you need to do is export an async function. Alternatively, return a new Promise:

// webpack.conf.js
module.exports = async function () {
  const response = await axios.get('http://myapi.com/api')
  const routes = response.map((response) => {
    return '/base/' + response.slug
  })

  return {
    plugins: [
      // ...
      new PrerenderSpaPlugin(
        path.join(__dirname, '../dist'),
        routes,
        {
          captureAfterTime: 5000
        }
      )
    ]
  }
}

If these options are not feasible, another approach is to create a separate task to make the request, save it to a json file, and then use require('./route-response.json') in your configuration.

Answer №2

Having a similar need, I set out to extract the list of routes from my API by creating a specialized script called prebuild.js

const fs = require('fs')
const axios = require('axios')

// Requesting data from the API
axios.get('http://myapi.com/api.php')
  .then(function(response) {
    const data = response.data
    try {
      // Saving the route list to a local file
      fs.writeFileSync('./route-response.js', data)
    } catch(err) {
      console.log(err)
    }
  })
  .catch(function(err) {
    console.log(err)
  })

The API sends over the information in the route-response.js file, structured and ready for direct use with npm. You can handle any necessary formatting within Node itself. Here's an example format:

module.exports = {
  theList: [
    '/',
    '/about',
    '/contact',
    '/login',
    '/register'
  ]
}

The aforementioned file is retrieved in webpack.prod.conf.js as follows:

...
const routeList = require('./route-response.js')
...
const webpackConfig = merge(baseWebpackConfig, {
  ...
  plugins: [
    ...
    new PrerenderSPAPlugin({
      staticDir: path.resolve(__dirname, '../dist'),
      routes: routeList.theList,
      renderer: new PuppeteerRenderer()
    })
    ...
  ]
  ...
})

Finally, include the prebuild script in your package.json

  • prebuild: runs before the build process.
  • postbuild: runs after the build process.

Here's how you can add it:

...
"scripts": {
  "dev": "node build/dev-server.js",
  "prebuild": "node build/prebuild.js",
  "build": "node build/build.js"
},
"dependencies": {
...

This streamlined setup allows me to simply execute npm run build

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

How to trigger a dispatch action in Nuxt.js store to update the state

After reading some articles on the topic, I am still struggling to understand it completely. This is my current issue: I have a component in Nuxt <a @click="openMenu">Open Menu</a> <div v-if="isUserNav"> ... </div> Essentially, ...

Assigning an identification number to specify the type of Chip

I am currently working on a project involving Material UI "Chips" that contain text and serve as references. Within the context of my project, I have Chips for both White Advantages and Black Advantages sections. However, there are instances where these Ch ...

Drag and drop elements within the Vue.Draggable component to rearrange them in the

I've been attempting to drag the same array to another array. I've spent almost 10 hours working on it and haven't been able to find a solution. I would really appreciate your help in figuring out where I'm going wrong. <draggab ...

File or directory does not exist: ENOENT error occurred while trying to scan 'pages'

Having trouble adding a sitemap to my nextjs app - when I go to http://localhost:3000/sitemap.xml, I get this error: Error: ENOENT: no such file or directory, scandir 'pages' https://i.sstatic.net/cxuvB.png The code in pages/sitemap.xml.js is a ...

Exploring the new features of utilizing buttons with the onClick method in the updated nextJS version 14.1.3

"implement customer" import React, { useState } from "react"; import { FaChevronLeft, FaChevronRight } from "react-icons/fa"; export default function HeroSlider() { const images = [ "/images/homepage/home-1.jpeg&qu ...

No Results Returned by Sails Query Following count() Query

Upon execution, the following code returns empty results. Although the correct values are retrieved without the Count query, the final response remains empty. Could this issue be related to a race condition? module.exports = { getSites: function (req, res ...

Submit Form Without Reloading -- and successfully submit it

I'm working on a form submission that triggers AJAX and PHP to load data without the need for page reloading. html/php <form method="POST"> <button type="submit" name="image1"> <button type="submit" name="image2"> <button ...

What is the best way to add the current date to a database?

code: <?php session_start(); if(isset($_POST['enq'])) { extract($_POST); $query = mysqli_query($link, "SELECT * FROM enquires2 WHERE email = '".$email. "'"); if(mysqli_num_rows($query) > 0) { echo '<script&g ...

execute numerous Jssor Caption instances simultaneously

I have a Jssor slider and I want to create an animation for the first slide. My goal is to make two images come from the sides and merge in the center. I tried using a div for each image with a caption, and it works well. However, the second image starts ...

Tips for validating form input upon submission in Angular 6

Within my Angular application, I have successfully implemented form validators. However, I am aiming to trigger form validation specifically upon submission. This means that when the user clicks on the submit button and the form is invalid, the errors indi ...

Load Vue dynamically to implement reCAPTCHA script

I am looking for a way to dynamically load a script like recaptcha specifically within the Register.Vue / login.Vue component. <script src="https://www.google.com/recaptcha/api.js?onload=vueRecaptchaApiLoaded&render=explicit" async defer> </s ...

The function this.props.array.map is not defined

Currently, I am in the process of learning React and have been attempting to display an element for each user in a predefined array. However, upon testing, my browser keeps throwing an error stating that this.props.users.map is not a function. I have imple ...

Your search parameter is not formatted correctly

I am currently working on filtering a collection based on different fields such as name by extracting the values from the URL parameters. For example: http://localhost:3000/patient?filter=name:jack I have implemented a method to retrieve and convert these ...

Troubles arise when using $resource without initializing it with the new operator

Trying to utilize the Angular promise API in my application has left me feeling a bit puzzled. I set up a factory as shown in the code snippet below: factory('transport', function ($resource) { var baseUrl = "http://aw353/WebServer/odata/Pay ...

Utilizing PHP loops with the integration of a Datetimepicker

When using datetimepicker javascript for bootstrap, I encountered an issue where the instance works fine if there is only one input field or if it's the first of multiple fields. However, when there are multiple fields, the datetimepicker does not wor ...

Mysterious attributes - utilizing react and material-ui

In my current project, I am using react and material-ui. This is the code snippet from one of my components: <Dialog title="Dialog With Actions" actions={actions} modal={false} open={this.state.open} onRequestClose={this.handleClose ...

``There Seems to be an Issue with Loading Content in Tabs

Hey! I'm encountering an issue with my jquery tabs. The first tab content loads fine, but when I select another tab, the content doesn't display. Then, when I try to go back to the first tab, it doesn't load either. Here's the HTML cod ...

JavaScript - Navigating through JSON object in reverse (from leaf to root) direction

FamilyTree= { "name":"Family", "photo":"images/family.jpg", "members":[ { "name":"Parent", "photo":"images/parent.jpg", "relationships":[ { "name":"Spouse", "photo":"images/spouse.jpg" }, ...

Retrieve the text content from the HTML document

I'm facing a beginner's challenge. I have a div element and I want to extract the URL from the data-element attribute into a .json file Is there a way to do this? <div content="" id="preview" data-element="http://thereislink" class="sample ...

What could be causing React to throw an invalid hook error when using useRoutes?

I encountered an error while attempting to add a new route to my project. import React from "react"; import News from "./NewsComponents/News"; import Photos from "./PhotosComponents/Photos"; import Contact from "./Contact"; import Home from "./Home"; ...