outlookoffice365office-jsoffice-addinsoutlook-web-addins

How to Fix "Office.js is Loaded Outside of Office Client" Warning in Outlook Web


I open an Office dialog for SSO and after login I successfully get the code from the URL using this code:

const currentUrl = window.location.href;
console.log(currentUrl);

const getCodeFromUrl = (currentUrl) => {
    const params = new URLSearchParams(currentUrl.split('?')[1]);
    return params.get('code');
};

const code = getCodeFromUrl(currentUrl);
console.log('Code:', code);

Office.onReady(function (officeContext) {
    if (officeContext) {
        if (code) {
            Office.context.ui.messageParent(JSON.stringify(code));
        } else {
            console.log("code not found");
        }
    } else {
        console.log('Office context not available.');
    }
});

After getting the code, the dialog closes successfully on the desktop. However, when we test the same thing on Outlook Web, the dialog does not close and gives this warning and error:

Warning: Office.js is loaded outside of Office client

I got my code when I redirect to my html but here I got error

redirect.html?code=RIaDfTxLDxUvRWLZWNox0EcIeUz9FT:52 

Uncaught TypeError: Cannot read properties of undefined (reading 'messageParent')
        at redirect.html?code=RIaDfTxLDxUvRWLZWNox0EcIeUz9FT:52:39
        at office.js:76:25549
        at t (office.js:76:24950)
        at s (office.js:76:32645)
        at c (office.js:76:4373)
        at f.waitForFunction (office.js:76:4462)
        at z (office.js:76:33109)
        at HTMLScriptElement.m (office.js:76:6525)
    :3000/favicon.ico:1 
    **Failed to load resource**: the server responded with a status of 404 (Not Found)

Here is my office.js code:

let dialog;
Office.onReady(function (info) {
    if (info.host === Office.HostType.Outlook) {
        if (Office.context && Office.context.ui) {
            Office.context.ui.displayDialogAsync(
                authorizationUrl,
                { height: 80, width: 40, requireHTTPS: true, promptBeforeOpen: false },
                function (asyncResult) {
                    if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
                        dialog = asyncResult.value;
                        dialog.addEventHandler(Office.EventType.DialogMessageReceived, function (arg) {
                            const code = arg.message;
                            dialog.close();

                            // Invoke callback with the received code
                            callback(code);
                        });
                    } else {
                        console.log('Failed to open dialog:', asyncResult.error.message);
                    }
                }
            );
        } else {
            console.log('Office context or UI not available.');
        }
    } else {
        console.log('Office host is not Outlook.');
    }
});

How can I solve this issue?


Solution

  • I'm not sure exactly why you're running into that issue. Looks like the difference between my code and yours is that you're using onReady while I use initialize.

    Here's my working SSO Dialog

    <!DOCTYPE html>
    <html lang="en-US">
    <head>
    <title>Activate</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/png" href="/assets/images/icon32.png" />
    <script src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js" 
    type="text/javascript"></script>
    <script type="text/javascript">
      Office.initialize = function () {
        function getHashStringParameter(paramToRetrieve) {
          var hash = location.hash.substring(1);
          if (!hash) return null; // No hash available
    
          const urlParams = new URLSearchParams(hash);
          return urlParams.get(paramToRetrieve);
        }
    
        var idToken = getHashStringParameter("id_token");
        var accessToken = getHashStringParameter("access_token");
        var code = getHashStringParameter("code");
        if (idToken) {
          var messageObject = {};
          if (idToken !== null) {
            messageObject = {
              isSuccess: true,
              idToken: idToken,
              accessToken: accessToken,
              code: code,
              search: window.location.href,
            };
          } else {
            messageObject = { isSuccess: false, error: "idToken was null" };
          }
    
          // Tell the task pane about the outcome.
          Office.context.ui.messageParent(JSON.stringify(messageObject));
        }
      };
    </script>