OfficeDev / Office-Add-in-samples

Code samples for Office Add-in development on the Microsoft 365 platform.
MIT License
701 stars 775 forks source link

Blazor excel Addin sample: history.pushState is not a function #509

Open RK1PF opened 1 year ago

RK1PF commented 1 year ago

Note: This repo is only for questions related to its samples. If you have questions about how to use office.js or the Office developer platform, please post your question on https://stackoverflow.com. Tag your question with office-js or outlook-web-addins

Question I have encountered an issue while developing an Excel add-in using Blazor sample. Specifically, I am having difficulty using client-side routing in my Blazor application when the office.js script from the Office JavaScript API is loaded in the page.

When I attempt to use the NavigationManager.NavigateTo method to navigate to a new page in my application, I receive the following error in the browser console:

Uncaught (in promise) TypeError: history.pushState is not a function

This error occurs only when the office.js script is loaded in the page. When I remove the script, client-side routing works as expected.

I have attempted to work around this issue by using the NavigationManager.NavigateTo method with the forceLoad parameter set to true. This method works, but it is significantly slower than client-side routing, as it requires a full page reload each time a link is clicked.

I believe that this issue may be related to a conflict or compatibility issue between the office.js script and the client-side routing functionality in Blazor. However, I have been unable to identify a specific workaround or solution that allows me to use client-side routing without experiencing the history.pushState error.

Could you please investigate this issue and provide guidance on how to resolve it or optimize the performance of client-side routing in this scenario? I would greatly appreciate any assistance that you can provide.

Thank you for your attention.

AlexJerabek commented 1 year ago

Hi @RK1PF,

Thanks for reporting this issue. @aafvstam, is this something you could investigate?

aafvstam commented 1 year ago

I indeed already investigated the issue last year when I created the Blazor Office Add-in Samples as I ran into the same issue where OfficeJS is blocking the history stack like so👇🏻

    var isOutlookAndroid = _hostInfo.hostType == "outlook" && _hostInfo.hostPlatform == "android";
    if (!isOutlookAndroid) {
        window.history.replaceState = null;
        window.history.pushState = null;
    }

What is obscure is that there is a check if the host is running in Outlook on Android and if that is NOT the case it will block all access to the history replaceState and pushState. I somehow feel that the intended block would only be if it IS Outlook on Android as personally I can't imagine that it fails on all platforms except on Outlook on Android.

As the blocking code was in place, I used the NavigationManager.NavigateTo in the NavMenu.razor file to work around that, but indeed this is much slower than using the history option.

From the context of the analysis of the issue the blocking history code was added to support Internet Explorer 11 while today Internet Explorer has been deprecated.

There were two options proposed:

  1. Remove the 5 lines, there was a request for this posted here: https://github.com/OfficeDev/office-js/pull/2808/commits
  2. Work around by saving the history before loading the Office JS APIs and restoring it after loading as shown in here: https://github.com/OfficeDev/office-js/issues/2327

Like so:

<script type="text/javascript">
    window._historyCache = {
        replaceState: window.history.replaceState,
        pushState: window.history.pushState
    };
</script>

<script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"></script>

<script type="text/javascript">
    window.history.replaceState = window._historyCache.replaceState;
    window.history.pushState = window._historyCache.pushState;
</script>

@AlexJerabek I think you should take this back to the team and investigate if the proposed commit of removing the 5 lines can be implemented as it seems outdated to me given that IE is not to be used anymore (I even think the team stopped testing on IE compatibility) @RK1PF For the time being you can try using the workaround as shown in the example above (there are other options described in the issue posts injecting the same, so you need to look what serves you best here).

Hope this helps.

RK1PF commented 1 year ago

Thank you, I will try the workaround you showed

lucasgadams commented 11 months ago

@AlexJerabek @aafvstam is there an update here on getting this properly fixed and removing those 5 lines?

lucasgadams commented 11 months ago

And @RK1PF you might want to reopen this issue just so it can get properly looked at?

RK1PF commented 11 months ago

And @RK1PF you might want to reopen this issue just so it can get properly looked at?

I've ended up using React 😅

aafvstam commented 5 months ago

@RK1PF You reopened, so you still need it (other than my workaround I posted earlier)?

I believe to have read that this was fixed, but haven't tried it yet.

aafvstam commented 4 months ago
No response for some time, but I'll have a look at this next week (week of April 25th) ...
RK1PF commented 2 months ago

No response for some time, but I'll have a look at this next week (week of April 25th) ...

Tried it this week (first week of July) and the "issue by design" is still there. There are some ways to workaround mentioned earlier but it feels a bit sketchy.