Loading External Extensions in the Forge Viewer

October 7, 2017

    The 2.15 version of the Forge Viewer API has introduced the concept of external extensions, causing the small breaking change in the way extensions are being loaded, see that article if you missed it: Breaking change in Forge Viewer.loadExtension.

    Loading an extension will now return a Promise, which allows to potentially load the extension asynchronously. This becomes interesting when the extension code is located on an external script which can therefore be download on-demand only when the extension is needed, could be as result of a user enabling a specific feature or programmatically triggered by some more logic in your code. The idea is being able to break down a large web application into core logic that will be loaded at startup and external extensions that may not be needed when, for example, opening the home page of your cool web application.

    There are obviously number of ways to accomplish that with modern web programming, but today let's take a look at what you get out of the box when using the Forge Viewer API:

    In order to support external extensions for the Viewer itself, for example Markups or BimWalk extensions are loaded this way, the development team has added a method called registerExternalExtension on the extension manager, so why not using it for your own custom extensions?

    Let's start by writing a very basic self-contained extension: I place it in a file named external.js, notice that at the bottom of the file we self-register the extension and wrap the whole code in an IIFE:

(function(){

  'use strict';

  function MyExternalExtension(viewer, options) {

    Autodesk.Viewing.Extension.call(this, viewer, options)
  }

  MyExternalExtension.prototype = Object.create(Autodesk.Viewing.Extension.prototype)
  MyExternalExtension.prototype.constructor = MyExternalExtension

  var proto = MyExternalExtension.prototype

  proto.load = function () {

    console.log('External Extension loaded!')

    return true
  }

  proto.unload = function () {

    console.log('External Extension unloaded!')

    return true
  }

  proto.sayHello = function (name) {

    console.log('Hi ' + name + '!')

    return true
  }

  Autodesk.Viewing.theExtensionManager.registerExtension(
    'MyExternal.Extension.Id',
    MyExternalExtension)
})()

   You can now place the extension file external.js under some static route served by your server - or any other place that can be accessed by your app. For testing purpose I am putting it under /resources/extensions/

    At startup of your application, you can now register the external extension as follow, just replace the localhost:3000 by whatever your app is running on:

Autodesk.Viewing.theExtensionManager.registerExternalExtension(
  'MyExternal.Extension.Id',
  'http://localhost:3000/resources/extensions/external.js')

    And simply load the extension as any other when needed:

viewer.addEventListener(
  Autodesk.Viewing.GEOMETRY_LOADED_EVENT, () => {

    viewer.loadExtension('MyExternal.Extension.Id').then(
      function(externalExtension) {

        externalExtension.sayHello('Bob')
      })
  })

    Open your browser console and be amazed!

external extension demo

Posts by author

Philippe Leefsma
Cloud Fellow

I write JavaScript for the future 3D World Wide Web, A.K.A Forge Platform