How to render a SharePoint page in IE using EDGE mode without changing the master page

So you are running the latest version of Internet Explorer and you’re thinking: I should get good performance and better User Experience when accessing a SharePoint site. After all, Microsoft® has done allot of work to bring that browser closer to being standards compliant. Wrong!

SharePoint’s User Interface (UI) is a creature of habit. It’s coded to target specific versions of Internet Explorer (IE), which makes me think some group at the company is stuck in the early 2000’s. If you take a look at SharePoint 2010 page source, you will see this meta tag in the section:

<meta http-equiv="X-UA-Compatible" content="IE=8" />

This essentially tells Internet Explorer to render the page using the IE 8 rendering engine even if the current version of IE is a more recent one (ex. IE10 or IE11).

SharePoint 2013 is no better. Despite still not using the HTML5 standard header, it instructs IE to render the page using IE10:

<meta http-equiv="X-UA-Compatible" content="IE=10" />

This is why I always strongly suggest using a non-IE browser when using SharePoint.

In working an issue found by a user of MyBoarda SharePoint task management app that I have a available – I found that the problem was due to the page being rendered in IE8 mode. If I brought up the debugger in IE11 and switched the rending engine to EDGE (latest version), then the issue would not occur. Rather than spending time trying to find a code workaround for this version of IE, something I have decided to stop doing long ago, I instead researched if there is a way to force the MyBoard app page to be rendered using IE EDGE, but at the same time not impact the entire site.

Changing the Master page to include the meta tag to render the page in IE using the latest engine is not an option, since MyBoard is an app whose main feature is that it can be quickly used from any site in a SharePoint (it simply requires it to be placed in a Document Library). It’s also only a single page, thus impacting an entire site for the benefit of only one page is not good. There are also several posts on the web documenting the negative impacts to a SharePoint site if this is done – perhaps the main reason that SharePoint, by default, sets its rendering engine to a specific version of IE.

So what do we do? What options do we have?

Solution

The solution is to use a simple HTML file (I call it my “IE Loader”), which loads with a meta tag that instructs IE to render in EDGE mode, and show the MyBoard app page in that iframe. The reason this works is because IE can only set the rendering engine once per page load. Once set (by the “top” page) it cannot be changed and thus all pages loaded through an iframe are forced to EDGE mode.

Here is the HTML:


<!DOCTYPE html>
<html>
<head>
<!–
Set the IE rendering engine to EDGE and loads a given aspx file in an iframe,
thus forcing it to be rendered using the browser's latest rendering engine.
Usage: ie.aspx?file.aspx
The default page to be loaded, when this file is accessed, can be set below (url variable).
(c) 2015 | Paul Tavares (@paul_tavares)
Gist: https://gist.github.com/purtuga/95ce7b50b22adc545c79
Blog post: http://wp.me/p2kCXW-95
–>
<title></title>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<link rel="shortcut icon" href="/_layouts/15/images/favicon.ico" type="image/vnd.microsoft.icon" />
<link rel="shortcut icon" href="/_layouts/images/favicon.ico" type="image/vnd.microsoft.icon" />
</head>
<body style="margin:0px;overflow:hidden;">
<script type="text/javascript">
(function(window, document, location){
var iframe = document.createElement("iframe");
iframe.src = (function(){
var url = ""; //<– Set this to the page you want to be loaded by default when user accesses this file.
if (location.search && location.search.length > 1) {
url = location.search.substr(1);
} else {
if (!url) {
alert("No page to load!\nUsage: ie.aspx?pageToLoadHere.aspx");
return;
}
location.href = (
location.href.indexOf("?") > -1 ?
location.href.substr(0, location.href.indexOf("?")) :
location.href.indexOf("#") > -1 ?
location.href.substr(0, location.href.indexOf("#")) :
location.href
) +
"?" + url + location.hash;
}
if (location.hash) {
url += location.hash;
}
return url;
}());
if (!iframe.src) {return;}
iframe.hidefocus = true;
iframe.scrolling = "auto";
iframe.setAttribute("style", "border:none;width:100%;height:" + window.innerHeight + "px;");
document.body.appendChild(iframe);
window.addEventListener('resize', function(){
iframe.style.setProperty("height", window.innerHeight + "px");
});
setInterval(function(){
if (iframe.contentWindow.location.hash !== location.hash) {
location.hash = iframe.contentWindow.location.hash;
}
}, 500);
}(window, document, location));
</script>
</body>
</html>

view raw

ie.aspx

hosted with ❤ by GitHub

This file, named ie.aspx (yes, file extension is, and needs to be, ‘aspx’ instead of ‘html’), can simply be uploaded to a Document Library and it will load the file defined at line 26 (var url) by default.

The JavaScript code simply ensures that the iframe takes up the entire width and height of the browser window, and maintains those dimensions even when window is resized, thus providing the allusion to the user that its actually not in a frame. In addition, it supports providing the URL to the page that should be loaded via the ‘search’ parameter field. Example: the following URL

ie.aspx?/sites/sitename/documents/myCustomPage.aspx

will load the page at /sites/sitename/documents/myCustomPage.aspx in the iframe rendered using the latest version of IE.

A default page to be loaded should be set so that if a user clicks on this file they will not get an alert.

Some caveats and tips:

  • Displaying the page in an iframe means that all links that the user clicks on, will also be displayed on the iframe and potentially breaking form functionally. To get around this, one can further enhance the code above to “break” the iframe if the URL is changed to one that is not the page that was meant to be displayed in an iframe.
  • For non-IE browsers that may access the ie.aspx page, it may be desirable to also break the iframe and just show the intended page directly.
  • If using this workaround on a controlled page, code can be added to that page to detect if IE is being used and if so, whether the ie.aspx page is the one displaying it.

Conclusion
So the solution here will trigger IE to render a single page using the latest version of the browser while leaving the rest of the site intact. This approach also does not require any structural change to a site or the involvement of an IT department to implement. In my current use of it, I have additional code that further integrates the “IE viewer” with the app I have loaded in the iframe.

48 thoughts on “How to render a SharePoint page in IE using EDGE mode without changing the master page

    1. Sorry… Can’t help. IE9 and 8 to me are dead 🙂 … besides: the “edge” trick described here is meant for IE11 anyway. Maybe follow up with Microsoft support?

  1. You can also do this in C# code in a web part:
    protected override void OnLoad(EventArgs e)
    {
    base.OnLoad(e);
    HttpRequest request = HttpContext.Current.Request;

    System.Web.HttpBrowserCapabilities browser = request.Browser;

    if (browser.Browser == “IE” && browser.MajorVersion == 7)
    {
    HtmlMeta browserEngineToUse = new HtmlMeta();
    browserEngineToUse.HttpEquiv = “X-UA-Compatible”;
    browserEngineToUse.Content = “IE=EDGE”;
    Page.Header.Controls.AddAt(0, browserEngineToUse);
    }
    }

  2. Thank you Paul. Out portal configured to IE 10 in master page After loading this Iframe whenever the user clicks any other it is loaded in IE edge and that should be happen right. all other links should be in IE 10 . Also URL in the browser does not change after
    clicking on this iframe page

    1. Hi Dileep.
      Correct… When this approach is used, anything on the IE browser is shown in EDGE mode… IE does not support multiple concurrent modes within the same tab… The first one loaded wins and is the mode used until a full page (browser tab) refresh is done.
      Re: URL not being updated
      See other comments below… I have commented on that before and suggested solutions.

  3. Hi Paul,

    I don’t see a link in the body, and the GitHub link is dead. Do you still have this code lying around somewhere? This looks like exactly what I need to fix an issue I’m having with a specific page in SharePoint.

  4. Hi Paul.

    First off thanks so much, this helped out with all of the latest (ie8 not compatible) javascript libraries. My plan is to use ie.aspx as the start page and load up the home page through ie.aspx. Then if the user navigates to a different page, that page loads through the iframe. That part is working just fine, but the url obviously won’t correlate with the current link that the user clicked on. For instance I would like some like this

    The current start page shows the url as:
    http://ie.aspx?home.aspx

    If they clicked on a link that sends them to About.aspx, I want the user to see
    http://ie.aspx?About.aspx instead of http://ie.aspx?home.aspx

    The url never changes, which makes sense why, but is there anyway to grab the page url they requested and populate that in the url?

    Thanks!

    1. Hi Brian.
      For your use case, you need to change the code in my sample… Currently, the script shown in this post only keeps the “hash” portion of the URL (the “#value”) in sync with the “top” frame… this code is on line 61-63 and what it does is it looks at the content loaded inside of the iframe and then saves data to the URL bar (top most frame). Its hard to give you specifics because every use case is different, but hopefully this gives you enough to change the code to meet your needs. For example: you could save the entire URL of the page loaded inside of the iframe to the outermost frame, so that it looks very similar to what the user is viewing inside the iframe.

      The important thing is: Whatever you save to the URL of the outer frame is then used the script to reload that page (line 29 and 30) if the user happens to click Refresh on the browser.
      Also keep in mind that this only works if the pages inside the iframe are not x-domain, since browser security would prevent you from reading information from pages that are not served from the same domain.

      Hope this heps. Good luck.

      /Paul

    1. Hi JQ.
      That question is really outside the scope of this post.

      The short answer, however, is: That’s not possible.
      The best you can do is hide the page’s content (or redirect to a message/error page) if the user’s browser is not Internet Explorer.

      /Paul.

  5. HI Paul
    I can not see any link from where I can download this file, I want to use your ie.aspx in our SharePoint SPA project as our SP2010 is locked down on IE 8.0 Enterprise Mode.

    Regards
    Mian

      1. Paul, can you elaborate on”this solution will not work with enterprise mode” – are you saying that if we are using the enterprise version of SharePoint, your solution will not work? I wanted to check this before I make further efforts in this direction. Thank you.

  6. Hey Paul,

    Thank you so much for this guide. I had the exact same problem and i’ve come close to solving it. However, the website that i’m trying to load in the iFrame does not support it for security reasons. IE displays an error where it asks to open in a new window, which is not a favorable option for me. Would you happen to know of a way to work around this?

    1. Hi Sam. It sounds like the page you are trying to load is either from a different domain as the one hosting this solution or its web server is setup to not allow the display of it in frames from any site. In those cases, there is really nothing we can do from the browser.

  7. Hi Paul, is there any way to hide the html file in the URL?
    I would prefer visitors to see just the ASPX page url not the ?scriptcewp.html url.
    Can that be done to this script?

    1. Hi Brett…
      Yes, I think that is possible. Just set the URL on line 27 (`url` variable) and then use it without including anything on the URL (no ?page.html….)
      Disclaimer: Should work… 🙂

      1. Hi Paul, I’m not sure what you mean (no ?page.html….)
        How do I set the URL variable without the “?page.html” ?
        Do I comment out line 45?

    2. Hi Brett.
      I just took a closer look at the code in the aspx file, and I think what you want is:

      Replace line 25-51 with:

      iframe.src = "your-file-to-be-loaded-in-iframe"

      Also, you probably don’t need the code at line 60-64, so remove that as well.

      Just to confirm: instead of your users seeing something like this:

      docLib/ie.aspx?scriptcewp.html

      in the broswer’s address bar, you would like instead for them to only see:

      docLib/ie.aspx

      correct?

      1. Hi Paul, Thanks for those changes, it works great. It’s exactly what I was after, much appreciated for your time.

  8. This post has been really helpful for me, to get two pages working fine.
    I have got the links inside the iframe also to work correctly.

    However, the browser ‘Back’ and ‘Forward’ buttons are not working as expected.
    Is there any way out?

    1. Hi Robin.
      There are ways for you to keep the browser history updated, but it will complicated really quick. The easiest would be to have code from pages displayed inside the iframe set the hash portion of the “outer page” – basically the browser location bar. Then your putter page would have to manage the changes to the hash and update the iframe if the user moves back/forward. But like I said: this can get really messy.

      1. As you said, it would get unnecessarily complicated for my requirement.

        So, I have taken the easy way out.

        My issue was a dynamic dropdown not rendering properly in IE8 mode.

        I have modified my js and everything is working fine, without the extra iframe .

  9. Hi Paul, I’m thankful to have found your post. This is the work-around to end all work-arounds. Thanks for the time and effort you put to this.

    I got your code to work when I save it locally.. My trouble starts when I load the page from a sharepoint document library. The page loads fine but the frame’s height is not being set to the height of the browser window. Its only about 150px! Have you encountered this?

    1. No, I have not see this. It sounds like the JavaScript code is not running. That height sounds like the default height for an iframe. Do you see any errors in the browsers console?
      Also: if your company has “Enterprise mode” turned on, that could cause issues as well.

  10. Hi Paul,

    I’m a engineer but am so many years removed from writing code that I need a little assistance (if you are willing to give it). I modified your ie.aspx by adding the URL for my SharePoint (SP) page in line 26, as you instructed. I placed ie.aspx in a document library. But I am missing the last mile, the code instructs to goes to ie.aspx and execute it everytime someone loads my SP page. Whatever that code may be, I’m thinking I’ll put it a text editor, name it xxxx.html, upload the html file to the document library, and put a link to it in a content editor webpart.

    I’m thinking your instructions to Steve to write a javascript that does three things is what I should do, however, my skills fall short here. Any additional help you can provide would be most welcome.

    Thanks. 🙂

    1. Hi Elki.
      This is completely untested and so it may or may not work… here is the code I think you need to put into your sharepoint page that will make it use the ie.aspx wrapper:

      if (window.top.location.href.indexOf('ie.aspx') === -1) {
          window.top.location.href = 'path/to/your/ie.aspx?' + location.href;
      }
      

      Hope this helps.
      /Paul

  11. Hi Paul,

    First off, thanks for the great article. I believe this is exactly the solution I’m looking for. Would you mind elaborating on how one might modify the code to “break” the iframe if the URL is changed from the default URL? I’m fairly new to the world of HTML and JavaScript, so I apologize if the solution is obvious.

    1. Thanks Matt…
      To detect if the page initially loaded in the iframe has changed, you could use just add code to the current setInterval loop and check the iframe’s document url. Line 61 already does some checking like that, so you can extend it there… Or, if you don’t like the pulling approach, define the iframe’s onload method via javascript and then everytime it is triggered, check the URL of the document loaded.

      1. Hi Paul,

        Thank You so much for the article.

        I tried implementing above suggestion to break the iframe using iframe’s onload method. But how can I check URL when any link is clicked within iframe ? if i use “location.href” it will always be the one with ie.aspx.

        Thanks

      2. You are correct… You actually have to look at the iframe’s contentWindow object and check its location.href… like:

        iframe.contentWindow.location.href

        but note/warning: if the page loaded in the iframe is CORS, then you will likely not be able to do that… (Security feature).

      3. Hi Paul, Thanks for the help! May I know the exact changes needed to be done on line 61 so that it “breaks” the iframe? I’m new to html and javascript so I have no idea what to change. Thanks.

      4. Hi John…
        This is untested… so your mileage may vary… Here is an example:
        If you are using this workaround to load the following page: ie.aspx?/sites/sitename/documents/myCustomPage.aspx, and you want to break out of the iframe if the user (inside of the iframe) navigates to a different page, then line 61-63 would be replaced with something like:

        if (iframe.contentWindow.location.search !== location.search) {
            location.href = iframe.contentWindow.location.href;
        }
        

        Hope this helps.

        /paul

      5. Thank You so much Paul. I really appreciate all your help. As you suggested below worked beautifully I replaced Line no 60 to 64 with

        document.getElementById('MyFrame').onload= function() {
        		          if (iframe.contentWindow.location.href.indexOf("PageYouWantToBeLoadediniFrame.aspx") === -1 ) {
                      window.top.location.href = iframe.contentWindow.location.href;				
                    }
        		}
        
  12. Stumbled across this and I feel like this could help my situation. However, I need a little help to implement.

    Issue: (DispForm.aspx) Starting with a regular Item list, a list owner will pick a line item, hover over an item name, and copy the URL.(copy shortcut). Next, they paste into an email and send to users to go review and edit the item if needed. However, when the user selects the link, the header to the DispForm is off the page and no way to get to it. Presumably due to, too many columns. I am running IE 11, and Pressing F12 in my browser shows Document mode is set to 8 (Default)

    I understand this is an HTML file, that would need to be renamed with ASPX extension and placed within a doc library on the site and Line 26 would need to be edited to point to my dispform.aspx path???

    If yes, how to I put this together so that when a user receives their email, and clicks on the URL and the DispForm is triggered to display the data, it will process your workaround.

    1. Hi Steve.
      I think I understood what you are trying to do.
      In order to handle your situation, where a user might have a URL directly to the item (dispform.aspx), you will need to add some javascript code to the dispform itself. That piece of javascript will need to do the following:

      1. Check if the page is being displayed in an iframe
      2. If in an iframe: check that the parent page is your “force edge mode” page (I named mine ie.aspx).
      3. If either condition above fails (not in an iframe or not your work-around page), then reload the page by pointing at the ie.aspx file (such as: ie.aspx?/sites/sitename/Lists/Tasks/DispForm.aspx?ID=123

      To get the code into the DispForm you could use a Content Editor webpart – you will find several post on how to do that.

      Hope this is clear and helps you to find a solution.

      /Paul

Comments are closed.