javascriptoutlook-addinoffice-jsoutlook-web-addinsoffice-js-helpers

Conditionally load Office.js when webapp is loaded as Outlook Add-in


I'm currently building a web application that can be loaded both as a standalone version in the browser and as an Outlook Add-In. To make use of the Outlook environment, I'm loading office.js within the layout of my web app. I'd like to check whether the webapp is loaded within Outlook (as an add-in) or as a web-app in the browser, so that I can conditionally hide features that require the app to run within Outlook.

According to the existant question on the topic (found here: Check if Office.js is loaded outside of Office client) office-js-helpers provide that kind of information through the use of

OfficeHelpers.Utilities.host

This returns either "outlook" or undefined depending on the context, which is exactly what I'm looking for (with the caveat that you first load office.js and then another to script to check whether office.js is actually needed). Unfortunately I have to support older releases of Outlook for which the solution above returns undefined even when loaded within outlook (up to 2 years behind the recent version - no change in sight).

Interestingly enough, office.js itself (or rather a dependency of it, o15apptofilemappingtable.js, https://appsforoffice.microsoft.com/lib/1.1/hosted/o15apptofilemappingtable.js) already has a line in the minified JavaScript that is able to figure out that office.js is loaded outside of an Outlook environment and prints a warning:

if(d._hostInfo.isRichClient){var e,a,u="Warning: Office.js is loaded outside of Office client",

Again this is exactly what I'm looking for, but I can't seem to wrap my head around how I could implement a check like that myself. I'm aware that you can check whether Office.js is fully loaded through the use of Office.onReady()(as seen here: https://learn.microsoft.com/en-us/office/dev/add-ins/develop/understanding-the-javascript-api-for-office), yet what I want is to check BEFORE office.js is loaded whether or not it is actually necessary (which it isn't when the application runs outside the Outlook environment).

Did someone run into a similar scenario and might share his insight?


Solution

  • One simple option to consider is adding a query parameter to the add-in's URL in the manifest. Then when that query parameter is missing, you know the application is running directly in a web browser. This method can also be used to distinguish between multiple URLs in the manifest that load the same page.

    For example, the manifest URL would look something like:

    <SourceLocation DefaultValue="https://.../taskpane.html?host=Outlook" />
    

    One benefit of this approach is you can skip loading Office.js altogether if you choose to.

    Another approach would be to call an API after Office.js has loaded. Building on your example, there's a similar Outlook API named Office.context.mailbox.diagnostics.hostName, and it's available in older versions of Outlook (The API's requirement set version is 1.0, which is the lowest version).

    But actually, when not running in Outlook, Office.js will not load Outlook APIs, and Office.context.mailbox is undefined. So, in javascript, you would just check whether Office.context.mailbox is defined.

    As pointed out in the question, calling any Office API requires waiting until Office.initialize or Office.onReady() has been called, so it's not the preferred option for the best performance.