How to URL changes, Browser refresh, route Navigation in Vue

How to URL changes, Browser refresh, route Navigation in Vue

Every once in a while in Vue, you want to prevent the user from navigating away from a route or reloading the page. If that's the case, you need to know "How to prevent browser refresh, URL changes, or route navigation in Vue" in this post.

Every once in a while in Vue, you want to prevent the user from navigating away from a route or reloading the page. For example, perhaps they made changes to a form without saving.

This behavior is not immediately available, but it’s relatively easy to accomplish.

First, we’ll need some sort of condition to track whether or not the user can navigate away. It may be different in your case, but for this example, we’ll have a boolean tracking whether the user is editing something.

<script>
export default {
  data: () => ({
    isEditing: false
  })
</script>

Prevent URL change and/or page reload.

Next, we need to add some logic to prevent the user from going to a new URL, or reloading the page while our isEditing is true. Fortunately, the browser has a native beforeunload event just for this.

We’ll add it to the beforeMount hook so that we know we are not in a server-rendered environment:

<script>
export default {
  // ...
  beforeMount() {
    window.addEventListener("beforeunload", () => {
      if (!this.isEditing) return
      e.preventDefault()
      // Chrome requires returnValue to be set.
      e.returnValue = ""
    })
  }
}
</script>

Vue does a great job of automatically removing any event handlers that are added to the template, but any that we manually create should be cleaned up to avoid any memory leaks.

To do so, we will refactor our anonymous function into a named method so we can clean it up in the beforeDestroy hook:

<script>
export default {
  // ...
  beforeMount() {
    window.addEventListener("beforeunload", this.preventNav)
  },

  beforeDestroy() {
    window.removeEventListener("beforeunload", this.preventNav);
  },

  methods: {
    preventNav(event) {
      if (!this.isEditing) return
      event.preventDefault()
      event.returnValue = ""
    }
  }
}
</script>

If you prefer, you could also put the event listener logic together by using Vue’s $once method:

<script>
export default {
  // ...
  beforeMount() {
    window.addEventListener("beforeunload", this.preventNav)
    this.$once("hook:beforeDestroy", () => {
      window.removeEventListener("beforeunload", this.preventNav);
    })
  },

  methods: {
    preventNav(event) {
      if (!this.isEditing) return
      event.preventDefault()
      event.returnValue = ""
    }
  }
}
</script>

Prevent router navigation

Great! So far, our component will prevent a user accidentally losing their changes if the browser changes, but it’s likely that your route changes are actually handled by JavaScript. If that’s the case, you will also need to prevent the Vue router from navigating away.

For this, we can conveniently hook into the in-component navigation guard beforeRouteLeave (assuming you are using vue-router).

beforeRouteLeave, as the name implies, runs whenever you are about to navigate away from the current route. It provides us a few parameters to work with:

  • to: the route being navigated to.
  • from: the route you are about to leave.
  • next: th function used to invoke navigation. You can also use this to navigate to any other route you like.

For our purposes, we are only interested in the next parameter, and we can combine this with a confirm check to ask the user if they want to continue navigation:

<script>
export default {
  // ...
  beforeRouteLeave(to, from, next) {
    if (this.isEditing) {
      if (!window.confirm("Leave without saving?")) {
        return;
      }
    }
    next();
  }
}
</script>

Finishing up

With that, we have a nice little component that prevents a user from navigating away based on our logic. Of course, we did not actually implement any logic, but I will leave that up to you.

The whole thing looks like this:

<script>
export default {
  data: () => ({
    isEditing: false
  }),

  beforeMount() {
    window.addEventListener("beforeunload", this.preventNav)
    this.$once("hook:beforeDestroy", () => {
      window.removeEventListener("beforeunload", this.preventNav);
    })
  },

  beforeRouteLeave(to, from, next) {
    if (this.isEditing) {
      if (!window.confirm("Leave without saving?")) {
        return;
      }
    }
    next();
  },

  methods: {
    preventNav(e) {
      if (!this.isEditing) return
      e.preventDefault()
      e.returnValue = ""
    },
  },
}
</script>

Thank for reading !

vue javascript development frontend webdev

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Frontend Developers

Create a new web app or revamp your existing website? Every existing website or a web application that we see with an interactive and user-friendly interface are from Front-End developers who ensure that all visual effects come into existence....

How long does it take to develop/build an app?

This article covers A-Z about the mobile and web app development process and answers your question on how long does it take to develop/build an app.

How To Develop And Deploy Micro-Frontends Using Single-Spa Framework

In this article, we're going to develop an app composed of micro-frontends using single-spa and deploy it to Heroku. We'll set up continuous integration using Travis CI. Each CI pipeline will bundle the JavaScript for a micro-frontend app and then upload the resulting build artifacts to AWS S3.

Vue CLI installation – how to create VUE CLI project in Vue 3?

Vue.js keeps on evolving thanks to continuous efforts of the open-source community. One of the most interesting recent changes in Vue 3 is the new improved version of Vue CLI. You can use it to configure a new project in a much faster and more streamlined way than ever before, using the command line interface. How to do it? I’m going to walk you through the entire process so sit back.

Creating a Custom Tooltip Component in Vue

There are plenty of libraries out there that will have you up and running with a good tooltip solution in minutes. However, if you are like me, you are sick and tired of giant dependency trees that have the distinct possibility of breaking at any time.