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:
Register
PresentationRpcInterface
when initializingIModelHost
. The way it's done depends on IModelHost specialization, but in any case that's similar to how any otherRpcInterface
is registered. A couple of examples:For a web app,
IModelHost
has to be initialized first and required RPC interfaces need to be passed toBentleyCloudRpcManager.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); // create a basic express web server const port = Number(process.env.PORT || 3001); const server = new IModelJsExpressServer(rpcConfig.protocol); 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 = { webResourcesPath: path.join(__dirname, "..", "..", "..", "build"), rpcInterfaces, developmentServer: process.env.NODE_ENV === "development", ipcHandlers: [SampleIpcHandler], }; const iModelHost: IModelHostOptions = {}; let authClient; if (process.env.IMJS_OIDC_ELECTRON_TEST_CLIENT_ID && process.env.IMJS_OIDC_ELECTRON_TEST_REDIRECT_URI && process.env.IMJS_OIDC_ELECTRON_TEST_SCOPES) { authClient = new ElectronMainAuthorization({ clientId: process.env.IMJS_OIDC_ELECTRON_TEST_CLIENT_ID, redirectUri: process.env.IMJS_OIDC_ELECTRON_TEST_REDIRECT_URI, scope: process.env.IMJS_OIDC_ELECTRON_TEST_SCOPES, }); iModelHost.authorizationClient = authClient; } await ElectronHost.startup({ electronHost, iModelHost }); if (authClient) await authClient.signInSilent(); await ElectronHost.openMainWindow();
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 2 steps:
Register
PresentationRpcInterface
when initializingIModelApp
. That's done by making sure the interface is included into the list ofrpcInterfaces
when callingstartup
onIModelApp
or one of its specializations.import { PresentationRpcInterface } from "@itwin/presentation-common"; const rpcInterfaces = [...otherRpcInterfaces, PresentationRpcInterface]; const iModelAppOpts: IModelAppOptions = { rpcInterfaces, }; await ElectronApp.startup({ iModelApp: iModelAppOpts });
Note: The above example uses
ElectronApp
, but it's similar with other specializations likeWebViewerApp
.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], // specify the preferred unit system activeUnitSystem: "metric", }, favorites: { storage: createFavoritePropertiesStorage(DefaultFavoritePropertiesStorageTypes.UserPreferencesStorage), }, });
Last Updated: 30 November, 2023