diff --git a/docs/api/README.md b/docs/api/README.md
index 5ec2560af..5e0c1f930 100644
--- a/docs/api/README.md
+++ b/docs/api/README.md
@@ -438,6 +438,18 @@ Register a callback which will be called when an error is caught during a route
 
 - An error occurred when trying to resolve an async component that is required to render a route.
 
+### router.onAbort
+
+Signature:
+
+```js
+router.onAbort(callback)
+```
+
+Register a callback which will be called when an a route navigation return false (`next(false)`).
+
+Note: this is only supported in 3.4.2+ and < 4.0 versions.
+
 ## The Route Object
 
 A **route object** represents the state of the current active route. It contains parsed information of the current URL and the **route records** matched by the URL.
diff --git a/docs/guide/advanced/navigation-guards.md b/docs/guide/advanced/navigation-guards.md
index e68137457..28530d9c7 100644
--- a/docs/guide/advanced/navigation-guards.md
+++ b/docs/guide/advanced/navigation-guards.md
@@ -30,7 +30,7 @@ Every guard function receives three arguments:
 
   - **`next()`**: move on to the next hook in the pipeline. If no hooks are left, the navigation is **confirmed**.
 
-  - **`next(false)`**: abort the current navigation. If the browser URL was changed (either manually by the user or via back button), it will be reset to that of the `from` route.
+  - **`next(false)`**: abort the current navigation. If the browser URL was changed (either manually by the user or via back button), it will be reset to that of the `from` route. (3.4.2+ and < 4.0) will be passed to callbacks registered via [`router.onAbort()`](../../api/#router-onabort).
 
   - **`next('/')` or `next({ path: '/' })`**: redirect to a different location. The current navigation will be aborted and a new one will be started. You can pass any location object to `next`, which allows you to specify options like `replace: true`, `name: 'home'` and any option used in [`router-link`'s `to` prop](../../api/#to) or [`router.push`](../../api/#router-push)
 
diff --git a/src/history/base.js b/src/history/base.js
index 072cfb8e8..2b23d7165 100644
--- a/src/history/base.js
+++ b/src/history/base.js
@@ -31,6 +31,7 @@ export class History {
   readyCbs: Array<Function>
   readyErrorCbs: Array<Function>
   errorCbs: Array<Function>
+  abortCbs: Array<Function>
   listeners: Array<Function>
   cleanupListeners: Function
 
@@ -56,6 +57,7 @@ export class History {
     this.readyCbs = []
     this.readyErrorCbs = []
     this.errorCbs = []
+    this.abortCbs = []
     this.listeners = []
   }
 
@@ -78,6 +80,10 @@ export class History {
     this.errorCbs.push(errorCb)
   }
 
+  onAbort (abortCb: Function) {
+    this.abortCbs.push(abortCb)
+  }
+
   transitionTo (
     location: RawLocation,
     onComplete?: Function,
@@ -141,15 +147,27 @@ export class History {
       // changed after adding errors with
       // https://github.com/vuejs/vue-router/pull/3047 before that change,
       // redirect and aborted navigation would produce an err == null
-      if (!isNavigationFailure(err) && isError(err)) {
-        if (this.errorCbs.length) {
-          this.errorCbs.forEach(cb => {
-            cb(err)
-          })
-        } else {
-          warn(false, 'uncaught error during route navigation:')
-          console.error(err)
-        }
+      if (!isNavigationFailure(err)) {
+		if(isError(err)) {
+			if (this.errorCbs.length) {
+			  this.errorCbs.forEach(cb => {
+				cb(err)
+			  })
+			} else {
+			  warn(false, 'uncaught error during route navigation:')
+			  console.error(err)
+			}
+		}
+		else if(err === false) {
+			if (this.abortCbs.length) {
+			  this.abortCbs.forEach(cb => {
+				cb(err)
+			  })
+			} else {
+			  warn(false, 'uncaught error during route navigation:')
+			  console.error(err)
+			}
+		}
       }
       onAbort && onAbort(err)
     }
diff --git a/src/index.js b/src/index.js
index 22ecff96d..1d42ebd62 100644
--- a/src/index.js
+++ b/src/index.js
@@ -167,6 +167,10 @@ export default class VueRouter {
     this.history.onError(errorCb)
   }
 
+  onAbort (abortCb: Function) {
+    this.history.onAbort(abortCb)
+  }
+
   push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
     // $flow-disable-line
     if (!onComplete && !onAbort && typeof Promise !== 'undefined') {
diff --git a/types/router.d.ts b/types/router.d.ts
index 07f912eb6..1e4db5a01 100644
--- a/types/router.d.ts
+++ b/types/router.d.ts
@@ -46,6 +46,7 @@ export declare class VueRouter {
   getMatchedComponents(to?: RawLocation | Route): Component[]
   onReady(cb: Function, errorCb?: ErrorHandler): void
   onError(cb: ErrorHandler): void
+  onAbort(cb: ErrorHandler): void
   addRoutes(routes: RouteConfig[]): void
   resolve(
     to: RawLocation,