Vue-router: Regular links not working in IE11

Created on 28 Nov 2017  路  11Comments  路  Source: vuejs/vue-router

Most helpful comment

Same problem here with Vue.js v2.5.16 and vue-router v3.0.1
@chrisbethelepb workarounds works for me.

Here is another implementation:

// router and IE 11 workaround. see: https://github.com/vuejs/vue-router/issues/1911
const IE11RouterFix = {
    methods: {
        hashChangeHandler: function() { this.$router.push(window.location.hash.substring(1, window.location.hash.length)); },
        isIE11: function() { return !!window.MSInputMethodContext && !!document.documentMode; }
    },
    mounted: function() { if ( this.isIE11() ) { window.addEventListener('hashchange', this.hashChangeHandler); } },
    destroyed: function() { if ( this.isIE11() ) { window.removeEventListener('hashchange', this.hashChangeHandler); } }
};

new Vue({
    /* your stuff */
    mixins: [IE11RouterFix],
});

All 11 comments

You have to use router-link to navigate within the app

From the documentation i know that the preferred way would be using router-link instead of regular links: https://router.vuejs.org/en/api/router-link.html

But regular links were working up to vue-router 2.7.0. Was there a breaking change recently?

We have a special case where our links are created dynamically by setting the html to a div with the v-html attribute. I made a quick test and router-links are not working there. Do you have an idea how to workaround that?

Thanks in advance!

The PR that added this behaviour is at #1662.
I'm not sure if this is something we want to fix but it bothers me that it was working before and it isn't now...

Having similar issues in IE11 and had to rollback to 2.7.0

In our case we have a menu fragment on the page that is not in Vue and just uses regular anchor tags which will trigger navigation change. Would be great to keep this especially for legacy applications where Vue apps are embedded partially in a page.

This works in chrome and firefox of course.

Here's a workaround that worked for me:

  • Add this to your Vue app that implements the router:
      methods: {
        hashChangeHandler: function() {
          var target = window.location.hash;
          this.$router.push(target.substring(1, target.length));
        }
      },
      mounted: function() {
        // fix for IE 11
        if (!!window.MSInputMethodContext && !!document.documentMode) {
          window.addEventListener('hashchange', this.hashChangeHandler);
        }
      },
      destroyed: function() {
        // fix for IE 11
        if (!!window.MSInputMethodContext && !!document.documentMode) {
          window.removeEventListener('hashchange', this.hashChangeHandler);
        }
      }

!!window.MSInputMethodContext && !!document.documentMode is just a quick truthy check that only evaluates to true for IE 11.

Working demo: https://jsfiddle.net/5r5pmLqw/

I solved it with babel: installing presets (stage-0, stage-1, stage-2, stage-3, env and es2015)
Here is how to install presets:
babel preset env
and adding them to my .babelrc:
{ "presets": ["env", "stage-0" "stage-1", "stage-2", "stage-3" , "es2015"] }

Same problem here with Vue.js v2.5.16 and vue-router v3.0.1
@chrisbethelepb workarounds works for me.

Here is another implementation:

// router and IE 11 workaround. see: https://github.com/vuejs/vue-router/issues/1911
const IE11RouterFix = {
    methods: {
        hashChangeHandler: function() { this.$router.push(window.location.hash.substring(1, window.location.hash.length)); },
        isIE11: function() { return !!window.MSInputMethodContext && !!document.documentMode; }
    },
    mounted: function() { if ( this.isIE11() ) { window.addEventListener('hashchange', this.hashChangeHandler); } },
    destroyed: function() { if ( this.isIE11() ) { window.removeEventListener('hashchange', this.hashChangeHandler); } }
};

new Vue({
    /* your stuff */
    mixins: [IE11RouterFix],
});

I think this is a bug that is worth fixing, especially because hash mode is the current default mode. I'm more than happy to help with a fix.

The root cause of the problem was introduced with this commit https://github.com/vuejs/vue-router/commit/1422eb51584139d210a2065d1d384e36cd73b9de. As far as I understand, this was done to enable scroll position saving in hash mode. I'm not sure why this feature relies on popstate. Is there a technical reason, or is this by accident?

This change in combination with the faulty popstate event support in IE and Edge [1] broke the navigation via regular links (or manual URL changes) in said browsers. There is an open PR https://github.com/vuejs/vue-router/pull/1988 to fix this problem in IE11, but this ignores other affected version of IE.

The best fix, IMHO, is to revert history mode to the hashchange event and to not rely on the popstate event anymore. Then, we would need to find another way to support scroll position saving in hash mode. Otherwise we would break a feature that is already released.

Another option is to add affected browser versions to the supportsPushState exceptions https://github.com/vuejs/vue-router/blob/dev/src/util/push-state.js#L6. This would also break scroll position saving in hash mode, but only for affected browsers.

A third option is to incorporate a fix to work around the popstate event issues in IE and Edge. There are multiple proposals here and in a related issue https://github.com/vuejs/vue-router/issues/1849.

[1] https://developer.mozilla.org/de/docs/Web/Events/popstate#Browser_compatibility

Yes, the problem was 1422eb5. That's why I couldn't merge #1988, it would have broken that feature that has been around for a long time. I didn't realize this issue could be a duplicate of #1849

There are other workarounds I thought about like listening to both events in IE 10/11 and Edge and filter out duplicates but it creates spaghetti code that I'm not happy with...

You can try working on a solution if you want

Was this page helpful?
0 / 5 - 0 ratings