Quickstart

This page gets you from an empty dashlet.js to a working dashlet that behaves the same in the webclient, the rich client, and standalone. What each environment actually does, and how the library decides: Environments and detection.

1. Install

Make the package available to your dashlet build:

npm install ecmind-blue-dashlet

(or a local path to the repository, if you build against the source checkout). The package is framework-agnostic with zero runtime dependencies; it ships dual ESM + CJS output, so it works from vanilla JS, React, Angular, or any other environment without modification.

2. The single rule

Call installDashletGlobal(options) first, at the top level of the dashlet script, before anything that could be deferred. The rich client fires its first window.osDashletInit call without waiting for load; the library therefore installs its global synchronously at import time and buffers every host call that arrives before installDashletGlobal runs.

3. The minimal dashlet

// dashlet.js — the dashlet page
import { installDashletGlobal } from 'ecmind-blue-dashlet';

// FIRST. Top level. Before any framework setup, imports of UI code, etc.
const dashlet = installDashletGlobal();

dashlet.init.then((ctx) => {
    // ctx is the normalized InitContext in every environment:
    //   ctx.environment: 'webclient' | 'richClient' | 'standalone'
    //   ctx.clientVersion, ctx.language, ctx.session, ctx.user,
    //   ctx.selection (SelectedEntry[]), ctx.lastSelectedEntry, ctx.location, ctx.raw
    render(ctx);
});

dashlet.onUpdate((ctx) => {
    // later selection / context changes (webclient onUpdate, rich-client callbacks)
    rerender(ctx);
});

No options needed — that is the default. In the webclient the wire runs in learning mode: it anchors the host origin from the first accepted onInit (see Origin configuration). If you already know the origin, pass expectedOrigin to switch it to strict mode.

4. What the init promise guarantees

  • init resolves exactly once and never rejects — including the standalone degraded state, which is an observable fallback, not an error. See Standalone operation.

  • It is bounded by the configured timeouts (DashletOptions), so the dashlet never hangs.

  • In every environment it resolves to the same normalized InitContext; the environment only changes which wire is live, not the shape your code receives.

5. Your first host calls

const dashlet = installDashletGlobal();
await dashlet.init;

await dashlet.openIndexData({ inNewTab: false, mode: 'view', objectId: '1024' });
await dashlet.getSelectedObjects(); // [{ objectId: 1024, objectTypeId: 262145 }, …]

The seven portable methods route through the same dispatch table as call(method, params), so the typed facade and the string-based call cannot drift. One webclient quirk to know before you call openHitListByIds: unless inNewTab === true, the post carries no msgId and resolves immediately — the host opens the hit list in the current tab, which destroys the dashlet’s iframe before a reply could arrive. In standalone, every facade method rejects with the bounded TimeoutError — render a fallback instead of waiting.

6. Where to go next