npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ng2-adsk-forge-viewer

v2.0.2

Published

Angular wrapper for Autodesk Forge Viewer

Readme

Angular Autodesk Forge Viewer

Build Status Viewer

Angular wrapper for the Autodesk Forge Viewer.

The wrapper was designed to meet the following requirements:

  • A viewer component that can be dropped in to an angular anywhere; the component would take care of loading required Scripts and CSS from Autodesk's servers, rather than requiring these to be declared in the index.html.
    • Ensure the viewer can be displayed and removed from the DOM via *ngIf
  • A basic viewer extension to subscribe to common viewer events - such as Seletion changed, object tree loaded etc. and expose these events on the component
  • TypeScript typings - which are now provided via Autodesk's official forge-viewer typings.
  • A component that can be dropped in to display a document thumbnail.

Dependencies

The library targets Angular 14.

Using the viewer component

Follow these steps to get the viewer working in your app.

A full demonstration of how to use the the library can be found on StackBlitz - https://stackblitz.com/edit/angular-forge-viewer.

Step 1

Add the ng2-adsk-forge-viewer NPM package to your app - npm install ng2-adsk-forge-viewer --save or yarn add ng2-adsk-forge-viewer

Step 2

Add <adsk-forge-viewer></adsk-forge-viewer> element to your component html

component.html:

<adsk-forge-viewer [viewerOptions]="viewerOptions3d">
</adsk-forge-viewer>

Step 3

There is a specific flow of logic to initialize the viewer:

  1. Set viewerOptions
  2. The viewer is constructed, loads scripts/resources from Autodesk's servers
  3. The onViewerScriptsLoaded callback (optional) is called to indicate all viewer resources have been loaded
  4. A onViewerInitialized callback is called indicating the Viewer is ready (i.e. Autodesk.Viewing.Initializer has been called) and a model can be loaded
  5. The onViewerInitialized event is emitted and you can now load a model. The event arguments contain a reference to the viewer which can be used to set the documentId to load. E.g.:
public loadDocument(args: ViewerInitializedEvent) {
  args.viewerComponent.DocumentId = DOCUMENT_URN_GOES_HERE;
}
  • A helper method getDefaultViewerOptions can be used to get the most basic viewer options

Step 4

When the model has been loaded the onDocumentChanged event is emitted. This event can be used to define the view to display (by default, the viewer will load the first 3D viewable it can find).

An example of displaying a 2D viewable:

component.html:

<adsk-forge-viewer [viewerOptions]="viewerOptions2d"
                    (onDocumentChanged)="documentChanged($event)"></adsk-forge-viewer>

component.ts:

public documentChanged(event: DocumentChangedEvent) {
  const { document } = event;

  if (!document.getRoot()) return;

  const viewables = document.getRoot().search({ type: 'geometry', role: '2d' });
  if (viewables && viewables.length > 0) {
    event.viewerComponent.loadDocumentNode(document, viewables[0]);
  }
}

FAQ

1. What ViewerOptions can be used to initialise the Viewer Component?

The ViewerOptions interface is as follows:

interface ViewerOptions {
  initializerOptions: Autodesk.Viewing.InitializerOptions;
  viewerConfig?: Autodesk.Viewing.ViewerConfig;
  headlessViewer?: boolean;
  showFirstViewable?: boolean;
  enableMemoryManagement?: boolean;
  onViewerScriptsLoaded?: () => void;
  onViewerInitialized: (args: ViewerInitializedEvent) => void;
}

initializerOptions allows you to provide arguments for the Autodesk.Viewing.Initializer. One of the most important settings is how the Forge viewer is to obtain it's access token.

You can provide an access key as a string, but I'd recommend using the function - the viewer will call the function you provide to obtain a new token when required - e.g. when the viewer first initialises or when the current token held by the viewer is shortly expiring.

Your viewer options code would look something like this:

this.viewerOptions3d = {
  initializerOptions: {
    env: 'AutodeskProduction',
    getAccessToken: (onGetAccessToken: (token: string, expire: number) => void) => {
      // Call back-end API endpoint to get a new token
      // Pass new token and expire time to Viewer's callback method
      onGetAccessToken(ACCESS_TOKEN, EXPIRE_TIME);
    },
    api: 'derivativeV2',
  },
  onViewerInitialized: (args: ViewerInitializedEvent) => {
    // Load document in the viewer
    args.viewerComponent.DocumentId = 'DOCUMENT_URN_HERE';
  },
};

viewerConfig allows you to provide additional options to Viewer3D's registered with the viewing application. Such as whether to ues the light or dark theme, any extensions to register with the viewer etc.

2. How do I configure a 'headless' viewer?

By default, the viewer component will intialise a 'full' ViewingApplication with toolbar, navigation controls etc. If you want a 'headless viewer' without these additional bits of UI, set the headlessViewer of the ViewOptions to true:

this.viewerOptions3d = {
  initializerOptions: {
    env: 'AutodeskProduction',
    getAccessToken: (onGetAccessToken: (token: string, expire: number) => void) => {
      // Call back-end API endpoint to get a new token
      // Pass new token and expire time to Viewer's callback method
      onGetAccessToken(ACCESS_TOKEN, EXPIRE_TIME);
    },
    api: 'derivativeV2',
  },
  headlessViewer: true,
  onViewerInitialized: (args: ViewerInitializedEvent) => {
    // Load document in the viewer
    args.viewerComponent.DocumentId = 'DOCUMENT_URN_HERE';
  },
};

3. My model doesn't load

Some users have reported that the default viewable is not rendered and have had to resort to using the onDocumentChanged changed event to load a model in the viewer.

An implementation might look like the following:

app.component.html

<adsk-forge-viewer [viewerOptions]="viewerOptions2d"
                    (onDocumentChanged)="documentChanged($event)"></adsk-forge-viewer>

app.component.ts

public documentChanged(event: DocumentChangedEvent) {
  const { document } = event;

  if (!document.getRoot()) return;

  const viewables = document.getRoot().search({ type: 'geometry', role: '2d' });
  if (viewables && viewables.length > 0) {
    event.viewerComponent.loadDocumentNode(document, viewables[0]);
  }
}

Extensions

BasicExtension

The viewer component comes with a BasicExtension that it registers against all viewers. The basic extension captures a handful of events including:

  • Autodesk.Viewing.FIT_TO_VIEW_EVENT,
  • Autodesk.Viewing.FULLSCREEN_MODE_EVENT,
  • Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
  • Autodesk.Viewing.HIDE_EVENT,
  • Autodesk.Viewing.ISOLATE_EVENT,
  • Autodesk.Viewing.OBJECT_TREE_CREATED_EVENT,
  • Autodesk.Viewing.OBJECT_TREE_UNAVAILABLE_EVENT,
  • Autodesk.Viewing.RESET_EVENT,
  • Autodesk.Viewing.SELECTION_CHANGED_EVENT,
  • Autodesk.Viewing.SHOW_EVENT,

The viewer emits these events and should support most use cases. It's possible to obtain a reference to the BasicExtension via the viewer's basicExtension getter.

Creating your own extension

The BasicExtension is derived from an Extension that wraps up all the logic to register and unregister extensions with the Forge Viewer. It also contains logic to cast Forge Viewer event arguments to strongly typed TypeScript classes.

Your extension should derive from Extension and have a few basic properties and methods.

export class MyExtension extends Extension {
  // Extension must have a name
  public static extensionName: string = 'MyExtension';

  public load() {
    // Called when Forge Viewer loads your extension
  }

  public unload() {
    // Called when Forge Viewer unloads your extension
  }
}

Example viewer options to register and load the above extension:

this.viewerOptions3d = {
  initializerOptions: {
    env: 'AutodeskProduction',
    getAccessToken: (onGetAccessToken: (token: string, expire: number) => void) => {
      // Call back-end API endpoint to get a new token
      // Pass new token and expire time to Viewer's callback method
      onGetAccessToken(ACCESS_TOKEN, EXPIRE_TIME);
    },
    api: 'derivativeV2',
  },
  onViewerScriptsLoaded: () => {
    Extension.registerExtension(MyExtension.extensionName, MyExtension);
  },
  onViewerInitialized: (args: ViewerInitializedEvent) => {
    // Load document in the viewer
    args.viewerComponent.DocumentId = 'DOCUMENT_URN_HERE';
  },
};

Most of the methods in the abstract Extension class are protected. So they can be overriden in derived classes if required. For example, the BasicExtension overrides the registerExtension method to take a callback to let the viewer component know when the Extension has been registered.

Building the component

For instructions on how to develop the component (build, debug, test etc.), see (README_dev.md).