Setting up iTwin.js Presentation library

Before the Presentation library can be used, it needs to be properly initialized. Because of the nature of iTwin.js architecture, the library needs to be initialized on the backend and each frontend that is in use — just like the iTwin.js framework itself.

Backend

There are 2 main steps to enable Presentation library usage:

  1. Register PresentationRpcInterface when initializing IModelHost. The way it's done depends on IModelHost specialization, but in any case that's similar to how any other RpcInterface is registered. A couple of examples:

    • For a web app, IModelHost has to be initialized first and required RPC interfaces need to be passed to BentleyCloudRpcManager.initializeImpl:

      import { PresentationRpcInterface } from "@itwin/presentation-common";
      const rpcInterfaces = [...otherRpcInterfaces, PresentationRpcInterface];
      
      // initialize IModelHost
      await IModelHost.startup();
      
      // tell BentleyCloudRpcManager which RPC interfaces to handle
      const rpcConfig = BentleyCloudRpcManager.initializeImpl({ info: { title: "presentation-test-app", version: "v1.0" } }, rpcInterfaces); // eslint-disable-line @itwin/no-internal
      
      // create a basic express web server
      const port = Number(process.env.PORT || 3001);
      const server = new IModelJsExpressServer(rpcConfig.protocol); // eslint-disable-line @itwin/no-internal
      await server.initialize(port);
      
    • For an Electron app, required RPC interfaces are passed straight into ElectronHost.startup:

      import { PresentationRpcInterface } from "@itwin/presentation-common";
      const rpcInterfaces = [...otherRpcInterfaces, PresentationRpcInterface];
      
      const electronHost: ElectronHostOptions = {
        rpcInterfaces,
        developmentServer: process.env.NODE_ENV === "development",
        ipcHandlers: [SampleIpcHandler],
      };
      const iModelHost: IModelHostOptions = {};
      
      await ElectronHost.startup({ electronHost, iModelHost });
      await ElectronHost.openMainWindow();
      
  2. Initialize Presentation backend:

    import { Presentation, PresentationProps } from "@itwin/presentation-backend";
    // set up props for the presentation backend
    const presentationBackendProps: PresentationProps = {
      rulesetDirectories: [path.join("assets", "presentation_rules")],
    };
    // initialize presentation backend
    Presentation.initialize(presentationBackendProps);
    

Frontend

Similar to the backend, the frontend initialization consists of 3 steps:

  1. Initialize IModelApp.

    await IModelApp.startup(iModelAppOpts);
    
  2. Register PresentationRpcInterface in RPC system. That's done by making sure the interface is included into the list of RPC interfaces when initializing one of the RPC managers. The below example uses BentleyCloudRpcManager.

    import { PresentationRpcInterface } from "@itwin/presentation-common";
    const rpcInterfaces = [...otherRpcInterfaces, PresentationRpcInterface];
    BentleyCloudRpcManager.initializeClient(rpcParams, rpcInterfaces);
    
  3. Initialize Presentation frontend:

    import { createFavoritePropertiesStorage, DefaultFavoritePropertiesStorageTypes, Presentation } from "@itwin/presentation-frontend";
    await Presentation.initialize({
      presentation: {
        // specify locale for localizing presentation data, it can be changed afterwards
        activeLocale: IModelApp.localization.getLanguageList()[0],
        schemaContextProvider: (imodel) => MyAppFrontend.getSchemaContext(imodel),
      },
      favorites: {
        storage: createFavoritePropertiesStorage(DefaultFavoritePropertiesStorageTypes.UserPreferencesStorage),
      },
      selection: {
        // tell @itwin/presentation-frontend to use our selection storage - this enables interop with
        // unified selection storage used in this app
        selectionStorage: MyAppFrontend.selectionStorage,
      },
    });
    

Last Updated: 14 August, 2024