OfficeDev / office-js

A repo and NPM package for Office.js, corresponding to a copy of what gets published to the official "evergreen" Office.js CDN, at https://appsforoffice.microsoft.com/lib/1/hosted/office.js.
https://learn.microsoft.com/javascript/api/overview
Other
687 stars 94 forks source link

Conflict between Next.js router and Office.js #2327

Open lkedmi opened 2 years ago

lkedmi commented 2 years ago

Provide required information needed to triage your issue

I'm using Next.js as the framework for a Word plugin, trying to at least. Next.js has their own router implementation which gets overridden by Office.js. It's caused by this piece of code:

https://github.com/OfficeDev/office-js/blob/64d4977254fd85f5da5d73ef218cd63d65acbb23/dist/office.debug.js#L1963

In my case, this piece of code nullify both functions.

Your Environment

Expected behavior

Not override and nullify window.history.pushState when window.next is set.

Current behavior

The Next.js router breaks when loading Office.js

Steps to reproduce

  1. Start a new Next.js project
  2. Configure a simple manifest
  3. Add a link from one page to another
  4. Run the Word plugin
  5. Click the link

Link to live example(s)




Provide additional details




Context

I was hoping to build a Word plugin and base it on Next.js, but due to this behaviour, it doesn't looks like it's possible, which is a shame.

Useful logs

Thank you for taking the time to report an issue. Our triage team will respond to you in less than 72 hours. Normally, response time is <10 hours Monday through Friday. We do not triage on weekends.

AbidRahman-MSFT commented 2 years ago

This sounds like a compatibility issue with the next.js framework. @preethikakiru - any idea if we support the next.js framework for Office Add-ins?

preethikakiru commented 2 years ago

Hello @lkedmi, Thanks for your question, I'm currently doing some investigation into this and will get back to you soon! Best, Preethika

millerds commented 2 years ago

@preethikakiru this doesn't look like a DevX tooling problem. It looks like an office.js compatibility problem and should go to the office.js engineers.

lkedmi commented 2 years ago

I will say that I moved on to a more "classic" solution but it'll be nice if we could use modern meta frameworks to build office add-ins.

sureshjoshi commented 2 years ago

@lkedmi Could you please re-name this issue's title to not specify Next.js? Perhaps something like "Office.js should not null out history APIs"

I've had this problem with various React routers, and am currently having this issue with SvelteKit.

This is entirely a problem inside Office.js, which nulls out pushState and replaceState, and breaks modern routing libraries because IE11 does not have the HTML5 History APIs.

https://github.com/OfficeDev/office-js/blob/64d4977254fd85f5da5d73ef218cd63d65acbb23/dist/office.debug.js#L1960-L1964

The OfficeJS documents mention that IE11 is still used in the field, but it does not have first-class support, as referenced here: https://docs.microsoft.com/en-us/office/dev/add-ins/concepts/browsers-used-by-office-web-add-ins and https://docs.microsoft.com/en-us/office/dev/add-ins/develop/support-ie-11

  • Office on the web no longer opens in Internet Explorer. Consequently, AppSource no longer tests add-ins in Office on the web using Internet Explorer as the browser
  • AppSource still tests for combinations of platform and Office desktop versions that use Internet Explorer, however it only issues a warning when the add-in does not support Internet Explorer; the add-in is not rejected by AppSource.
  • The Script Lab tool no longer supports Internet Explorer.

Common workarounds:

Some people use NPM libraries which add history polyfills or support. With some routers, you can use HashRouter support (if they have it). I use variations of this silly workaround: https://stackoverflow.com/a/53662709/992509

<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>

The Request:

Could someone please remove those 5 lines of code and let modern browsers/routing be the norm, and let the rare failures on unsupported browsers be handled on a case-by-case basis.

IE11 is now retired and no longer supported by Microsoft. AppSource doesn't mandate IE11 support. Most Office variants (other than unsupported operating systems, or non-subscription Office purchases before 2020) can use the HTML5 history API.

Please delete those 5 lines, and add documentation surrounding the error that would appear if you use IE11 and try to use those APIs.

cc: @chiz-ms @xiaoyuMS

References:

This problem has come up a few times, with many workarounds. Here's a non-exhaustive list of the resources I've needed to look at while solving this issue in the past. The first issue is over 3 years old.

xiaoyuMS commented 2 years ago

@AbidRahman-MSFT @preethikakiru Does anybody know who is the contactor of office.js?

lucasgadams commented 1 year ago

Any update?

aorsten commented 8 months ago

We're also using NextJS, and are using the "silly workaround" mentioned by @sureshjoshi above.

Any updates here? Are there any other known NextJS incompatibilities?

tqmp commented 8 months ago

@aorsten I am also facing the same problem with nextjs. The workaround seems to not work anymore following the most recent outlook update.

aorsten commented 7 months ago

According to this, the problem is supposed to be fixed: https://github.com/OfficeDev/office-js/issues/1344#issuecomment-1977157671

Can anyone confirm?

lkedmi commented 5 months ago

I can't verify if this issue has been fixed or not but I am experimenting with placing the whole app behind an iframe and communicate with Word functionality with postMessage. It seems to be working but I'm curious if anyone had tried it before or if anyone can think of any downsides I'm missing with this approach?

RK1PF commented 4 months ago

According to this, the problem is supposed to be fixed: #1344 (comment)

Can anyone confirm?

Not fixed yet, I have tested with a Nextjs app, so it would not work with any modern web app that use modern routing

RK1PF commented 4 months ago

I can't verify if this issue has been fixed or not but I am experimenting with placing the whole app behind an iframe and communicate with Word functionality with postMessage. It seems to be working but I'm curious if anyone had tried it before or if anyone can think of any downsides I'm missing with this approach?

I'm not sure it really work using iframe, office.js needs to be hosted in plain "browser" top window. And you get the following warning if not: Warning: Office.js is loaded outside of Office client The add-in is not hosted in plain browser top window.

I'm curious to see how you are doing so?

lkedmi commented 4 months ago

@RK1PF (I had to put that project on hold for the time being but) the strategy I was using is as follows:

  1. Create a "shell" application which loads Office.js and an iframe to the "real" application, which covers the whole screen.
  2. Whenever the "real" application needs access to Office.js, it send a postMessage with the type of the operation and any metadata required.
  3. The "shell" application carries out the operation and provides feedback with postMessage back to the "real" application.

So essentially, the top most window is the one who is responsible to interact with Office.js, not the iframe.

This strategy seemed to be successful on my local machine but I haven't reached to a point where I'm publishing it to the Microsoft Office Add-ins Store.