Displaying a 404 error page in a Vue.js and Vue Router single-page application when a resource is not

Implementing Vue and Vue Router in a single page application (SPA) has presented me with a challenge. In one of my view components, I query a repository for a specific resource. If the resource cannot be found, I'd like to display a 404 error page without altering the URL.

For example, if a user visits /foo/non-existant-id, I want to show a custom 404 page instead of the usual content for the foo resource.

To clarify, here is how my router map is set up:

router.map({
  '/foo/:id': {name: 'foo-show', component: FooShowPage},

  // Utility routes
  '/': { name: 'home', component: HomePage },
  '*': { name: '404', component: NotFoundPage }
})

In my FooShowPage component, I handle this situation as follows:

ready () {
  // Fetch the foo object from the repository (app.foos)
  app.foos.fetchById(this.$route.params.id).then(foo => {
    this.foo = foo
  }).catch(e => {
    // If foo is not found, display a 404 page
    // Using this.$route.router.go({name: '404'}) does not work because the route is a wildcard 
    console.warn(e)
  })
}

In essence, I am looking for a way to dynamically replace the FooShowPage component with the NotFoundPage in the router view or redirect to a predefined 404 page while preserving the browsing history.

Answer №1

To ensure any unmatched routes are directed to a 404 page, it is important to establish a specific route for this purpose. In my coding approach, I utilize the router.redirect function following the mapping of routes.

router.map({
  '/': { name: 'home', component: HomePage },
  '/foo/:id': {name: 'foo-show', component: FooShowPage},
  '/404': {name: 'not-found', component: NotFound}
})

router.redirect({
    '*': '/404'
})

This setup guarantees that all routes which do not match those explicitly defined in the map will automatically redirect to the designated /404 page.

Answer №2

Discovered a useful tip on Vue.js forum regarding utilizing navigation guards:

import store from '../store'

{
  path: '/works/:work',
  name: 'work',
  component: Work,
  beforeEnter: (to, from, next) => {
    function validateID (id) {
      return store.getters.resourceByID(id) !== undefined
    }

    if (!validateID(to.params.id)) {
      next({ name: 'not-found' });
    }    
    next();
  }
},

Note: Remember to import store in order to access getters as discussed in this Github thread and this question

Still figuring out how to keep the same requested URL

Answer №3

After experimenting with different approaches, I have found a solution by implementing a global interceptor using Axios to handle all 404 responses coming from the API and redirecting them to the appropriate route. However, this method changes the URL to '/404' similar to what @Leo's answer suggested.

const http = axios.create({
  headers: {
    'X-Requested-With': 'XMLHttpRequest'
  }
});

// Implement global response interceptors
http.interceptors.response.use(function (response) {
  // For successful responses, proceed as usual
  return response;

}, function (error) {
  // If a 404 error is encountered, redirect to the error page while replacing the history
  if (error.response.status === 404) {
    return router.replace({ name: 'notfound' });
  }

  return Promise.reject(error);
});

export default http;

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

React hooks - Issue with updating state properties within sidebar display

When resizing the window, I have an event that will display either the desktop sidebar or the mobile sidebar. However, there are variables that are not immediately updated to show the sidebar correctly based on the window size. In a desktop window, this ca ...

CoffeeScript is failing to run the code

I'm attempting to use a click function to alter the CSS code and then run a function. Here is my current code: ready: -> $("#titleDD").click -> $("#titleDD").css('text-decoration', 'underline'); $("#catDD").css( ...

How come the array's length is not appearing on the browser screen?

Code: initialize: function() { this.todos = [ {id: 100, text: 'Rich'}, {id: 200, text: 'Dave'} ]; }, activeTodos: function() { this.todos = this.todos.length(function() { return this.todos; }); ...

Verify that a minimum of one checkbox has been ticked according to JavaScript guidelines, with appropriate notifications in case

Need help with displaying a message when no checkbox is checked. Currently implementing JavaScript rules and messages <form method="post" enctype="multipart/form-data name="english_registration_form" id="english_registration_form" > <div cl ...

Several directories for viewing in Node.js with Express

I have been researching different solutions, but I am still unsure about how to effectively integrate Express with multiple view folders. Imagine an Express application divided into distinct parts, each organized in its own subfolder: app +partA + ...

Tips for effectively managing dynamic xpaths

When conducting a search operation, I am required to select the text that is returned as a result. Each search will produce different xpaths. Below are examples of various xpaths returned during a search: .//*[@id='messageBoxForm']/div/div[1]/di ...

Is there a way to set a custom width or make the description responsive?

Is there a way to ensure that the description is responsive and automatically goes to the next line instead of extending horizontally? Although using textField could fix this issue, I also need to adjust the padding and outline. Are there any alternative s ...

JavaScript debugging causing system freeze

Currently, I am working on a project that involves using MVC and dropdown lists. My issue arises when the dropdown list changes, as there is some javascript code that needs to execute. To troubleshoot the problem of the system locking up every time I tried ...

Ensure that users must confirm their actions through a message prompt when attempting to exit the website

Looking to add a confirmation box that pops up when someone tries to leave my website. It's important to prevent any information from being lost if they accidentally navigate away. Can you provide detailed instructions on where exactly I should place ...

Learn how to effectively utilize templateURL in an express and angular project

Our project utilizes Express without any view engine. To set up static directories, we have the following: app.use(express.static(__dirname + '/public')); app.use(express.static(__dirname + '/view')); app.use(express.static(__dirname + ...

Tips on eliminating overlapping strokes

I'm having trouble with drawing an array of circles that are meant to intersect a series of lines. The issue I face is that if the circles overlap, a stroke appears underneath them which I want to remove. Does anyone have any suggestions on how to el ...

Unable to retrieve value from a hidden input field using JavaScript

My goal is to retrieve a value from a hidden inputbox using JavaScript. However, I am encountering issues where sometimes I receive an "undefined" error and other times there is no output at all. When I utilize alert(document.getElementById('hhh& ...

Having trouble replacing scss variables in react-h5-audio-player

I recently integrated react-h5-audio-player into my project and followed the instructions on the README page to customize the styles by updating the SCSS variables that control the colors. However, it appears that my custom styles are not being applied. An ...

Comparing JSON objects using Javascript and AngularJS

In the page I'm working on, there are several input fields where users can enter data such as text boxes and dropdowns. When a user fills in the data and clicks SAVE, certain checks and manipulations need to be done before the actual saving process st ...

"Troubleshooting: Issues with jQuery Counter Functionality

Hey there, I'm new to JavaScript and jQuery! I've got this form set up with Bootstrap's disabled class: Note: the 'disabled' class in bootstrap properly disables and enables the button based on conditions. <form action="" met ...

Steps for implementing remote modals in Bootstrap 5 using CS HTML

I'm attempting to implement a remote modal window in Bootstrap 5 with C# MVC. The endpoint for the modal partial view is configured correctly. According to this discussion on Github, all that needs to be done is to call some JavaScript. However, it ...

Form an array using the values that are returned

As I iterate through an object and extract elements, my console.log displays: ["item 1"] ["item 2"] ["item 3"] and so on. All I want is to create a new array formatted like this: ["item 1","item 2","item 3"]; ...

What's the best way to organize a list while implementing List Rendering in VueJS?

Currently, I am working on List Rendering in Vue2. The list is rendering correctly, but it appears ordered based on the data arrangement in the array. For better organization, I need to sort each item alphabetically by title. However, I am facing difficult ...

Using PHP functions in an AJAX request

I am currently attempting to execute a php loop upon clicking a radio button. I understand that ajax is necessary for this task, but as a beginner in ajax, I am struggling to achieve the desired result. Presently, I am unable to click the radio button at a ...

Can the URL be updated in Vue Router without navigating to a new page?

I am working on a Nuxt.js website and trying to implement a "Load more" button on the /catalog page. When clicking on the button, I want to load more products without navigating to a new URL like /catalog/page_2 (?page=2 is not an option). If I use $router ...