What is the best practice for preloading route data before navigating to the route?

When preparing to render a page for a specific route, my goal is to fetch the necessary data synchronously first. Ideally, I prefer to handle the data fetching within the page component, but I am open to doing it in the router files as well. I have experimented with different methods, but the challenge lies in the various ways components can be built and the differences in feature usage.

In my scenario, I am creating single file components using the Composition API and <script setup> syntax. The Vue Router documentation discusses "fetching before navigation" where options like beforeRouteEnter or beforeRouteUpdate are mentioned, but these are demonstrated using the Options API. Although there is a section for the Composition API which talks about utilizing onBeforeRouteUpdate within the setup() function, experimentation has led me to try out using <script setup>:

<script setup>
import { onBeforeRouteUpdate } from 'vue-router'

onBeforeRouteUpdate(() => {
  console.log('onBeforeRouteUpdate')
})
</script>

Unfortunately, this approach does not work as expected. A method that has shown some success is fetching the data in the router using the beforeEnter guard and then setting the data onto the meta property, which can be accessed on the route instance in the component:

beforeEnter: (to, from, next) => {
  fetch('https://pokeapi.co/api/v2/pokemon/ditto')
    .then(res => res.json())
    .then(res => {
    to.meta.pokemon = res;

    next();
  });
}

It's worth noting, however, that as indicated in the documentation, beforeEnter only triggers when entering the route. Changes in parameters will not trigger this again, requiring the setup of a watcher on the route in the component itself. At this point, it may have been simpler to include all this logic within the component directly.

Despite my efforts, I still haven't found an ideal solution for this process, but I'm open to suggestions and guidance. Any pointers or advice would be greatly appreciated. Thank you in advance.

Answer №1

If you're looking for a solution, consider using top level await with Vue. Check out this link: https://vuejs.org/api/sfc-script-setup.html#top-level-await

To implement this approach, simply wrap your RouterView component in a Suspense component like demonstrated here: https://vuejs.org/guide/built-ins/suspense.html#combining-with-other-components (make sure to exclude unnecessary components).

Keep in mind that the 'loading screen' will be visible during the initial request.

If you'd like to test it out, I've created a demo for you to explore: https://github.com/ileue/vue-top-level-await-demo

Answer №2

Initially, it's important to note that beforeRouteUpdate is specifically triggered when updating the current route, not when transitioning to another component or page as clarified here.

An instance where this lifecycle hook could be activated is shown below:

<button @click="$router.push({ hash: `#${Math.floor(Math.random() * 10)}` })">
  random hash
</button>

onBeforeRouteLeave functions smoothly when transitioning between pages.

In response to the initial inquiry, one approach is to incorporate a form of router middleware similar to how Nuxt handles it. This enables you to await an HTTP call and permit navigation only after it has been completed, thereby establishing a blockade effect during navigation.

Although I am unaware of how to implement this using the Composition API, it is known to function effectively with the Options API (numerous blog posts are available on this topic). Given that setup operates within its own lifecycle, certain aspects may pose challenges.

In summary, combining a traditional router middleware with a wrapper around your pages (like a layout) seems ideal in this scenario. This allows for a single watcher to monitor multiple pages simultaneously.

The effectiveness of these strategies largely depends on the organization and structure preferences of individual developers.


Skeleton screens impart a perception of swiftness compared to obstructive loading screens. Alternatively, utilizing prefetching (commonly included in Nuxt by default) can provide insights and potentially preload necessary assets before they are required. Various techniques in this realm can expedite network requests and enhance performance overall.

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

Ways to retrieve the text of the chosen radio button label with the help of jQuery

There is a radio button on my webpage that looks like this: <div id="someId"> <label class="radio-inline"> <input name="x" type="radio" onchange="GetSelectedVal();">Yes</label> <label class="radio-inline"> ...

Acquiring the item by referencing one of its property's values

Imagine you have a JSON structure that looks like this: [ { "name":"Foo" "nickname":"Lorem Ipsum" }, { "name":"Bar" "nickname":"Dolor S ...

What is the method for sending raw put data using the request npm package in a Node.js environment

How can I hit an API using the "require" npm package in Node? The API requires raw PUT data instead of PUT fields. Can anyone please guide me on how to achieve this using the request npm package? For example, here is the raw PUT data that needs to be sent ...

Using a jQuery UI dialog for multiple checkbox selection. The post array cannot be saved for a multi-select until the dialog is opened

CSS <td class="cell"> <a class="opener" id="opener_'.$iterator.'" href="#" rel="#type_dialog_<?= $iterator; ?>">Click here</a> <div id="type_dialog_<?= $iterator; ?>" name="t ...

Tips for adding a "Select All" feature to a dropdown list?

Currently, I have a dropdown list with a filter for IN and OUT values. The functionality is working as expected: <select class="form-select" style="max-width: 100px" [ngModel]="selectedBrand" (ngModelChange)="onChangeT ...

Display a custom error message containing a string in an Angular error alert

How can I extract a specific string from an error message? I'm trying to retrieve the phrase "Bad Request" from this particular error message "400 - Bad Request URL: put: Message: Http failure response for : 400 Bad Request Details: "Bad Request ...

The jQuery AJAX autocomplete result box is either too cramped or displaying numbers

I'm having some trouble setting up jQuery UI autocomplete with ajax in my project using CI 3.1.5. When I try to implement it, I either get a small result box or just the number of results. Here is my AJAX code snippet: $(".addClient").each(funct ...

Enhance the appearance of Ionic popups

Can someone help me with resizing a pop up? I've been struggling to get it right. This is the popup template in question: <ion-view> <ion-content scroll="false" class=""> test </ion-content> < ...

What could be causing my Node application to give a 404 error when making a POST request?

I'm at a loss trying to debug my app for what seems like a simple error, but I just can't locate it. Here is an overview of how my Express app is structured. My routes are set up as follows: var routes = require('./routes'); ... app.g ...

Utilize Haxe Macros to swap out the term "function" with "async function."

When I convert haxe to JavaScript, I need to make its methods asynchronous. Here is the original Haxe code: @:expose class Main implements IAsync { static function main() { trace("test"); } static function testAwait() { ...

Error messages from the Outlook Web add-in are presented as helpful information

I need assistance in showing error notifications. Here is my code: Office.context.mailbox.item.notificationMessages.addAsync("error", { type: "errorMessage", message: "The add-in encountered an issue while processing this message." }) The respons ...

The Image component in a test within Next.js was not wrapped in an act(...) during an update

After setting up a basic NextJS app with create-next-app and integrating Jest for testing, I encountered an error message stating "An update to Image inside a test was not wrapped in act(...)". The issue seems to be related to the Image component in NextJS ...

What is the best way to iterate through an array and dynamically output the values?

I am facing an issue with a function that retrieves values from an array, and I wish to dynamically return these values. const AvailableUserRoles = [ { label: 'Administrator', value: 1 }, { label: 'Count', value: ...

What is the process for incorporating custom controls into the Mantine Embla Carousel within a Next.js environment?

Check out this code snippet: import React from "react"; import { Container } from "@mantine/core"; import { Carousel } from "@mantine/carousel"; import { ArticleCard } from "@/components"; import { cards } from " ...

Incorporating custom HTML5 player to watch Youtube videos on my website

I'm trying to display YouTube videos on my website using a simple video tag. I've managed to retrieve the encoded url of the video from the page source and successfully download it through IDM, but when I try to use this URL as the source for an ...

What could be the reason behind Cesium viewer's failure to show a model after I upload it?

My application features a 3D map of a city with an "Add building" button. Upon clicking this button, a model of a building should be inserted into the map. However, all I see is a selection marker at the intended location without the actual building appea ...

Black-colored backdrop for Mui modal

Currently working with a mui modal and encountering an issue where the backdrop appears as solid black, despite setting it to be transparent. I attempted to adjust the color to transparent, but the issue persists. ...

Importing Vue and Vuex modules from separate files

Recently, I encountered an uncommon issue. I decided to keep my main.js and store.js files separate in a Vue project. In the store.js file, I imported Vuex, set up a new vuex store, and exported it. However, when importing this file into main.js and settin ...

"Techniques for incorporating a screen in Angular application (Switching between Edit and View modes) upon user interaction

We are currently working on a screen that requires the following development: This screen will have the following features: When clicking on a button, the fields should become editable. In the image provided, there is some repeated data, but in our case, ...

Leveraging deferred for linking loops involving several ajax requests

Despite the fact that several questions have been answered on this topic, none of them seem to be effective in this particular scenario. function login(u,p) { console.log(1); return $.post(url, {u,p}); } function out() { console.log(3); //a f ...