Skip to content

Dashboard state

Every addressable component owns a bag of named values. Both embed mechanisms expose the same component ids and value shapes; only the transport differs.

js
{
  "region-menu": { filter: "EMEA" },
  "date-range": { filter: ["2026-01-01", "2026-06-30"] }
}

Read state

js
function getState() {
  return new Promise((resolve) => {
    const requestId = crypto.randomUUID();

    function onMessage(event) {
      if (event.source !== frame.contentWindow || event.origin !== ridgeOrigin) return;
      if (event.data?.type !== "ridge:state" || event.data.requestId !== requestId) return;
      window.removeEventListener("message", onMessage);
      resolve(event.data.state);
    }

    window.addEventListener("message", onMessage);
    frame.contentWindow.postMessage({ type: "ridge:getState", requestId }, ridgeOrigin);
  });
}

const state = await getState();
js
await ridge.ready;

const state = ridge.getState(); // every component
const region = ridge.getState("region-menu"); // one component, or null

An inline read before ridge.ready throws. For an iframe, wait for ridge:ready before sending requests. Match replies by requestId because a host may have several reads in flight.

Write state

Writes merge by component id and state key. Omitted values are untouched; null clears a key.

js
frame.contentWindow.postMessage(
  {
    type: "ridge:setState",
    state: { "region-menu": { filter: "EMEA" } }
  },
  ridgeOrigin
);
js
const result = await ridge.setState({
  "region-menu": { filter: "EMEA" }
});

result.state; // full settled state
result.changed; // component ids that changed
result.errors; // rejected component writes

The iframe write is fire-and-forget. Listen for ridge:error to detect rejected component writes. The inline call returns partial-success details after queries and rendering settle.

To clear the filter in either example, write { "region-menu": { filter: null } }.

Discover the state schema

The state schema tells you which component ids and keys exist, what values they accept, and whether they are writable.

js
const requestId = crypto.randomUUID();
frame.contentWindow.postMessage({ type: "ridge:getStateSchema", requestId }, ridgeOrigin);

// Listen for:
// { type: "ridge:stateSchema", requestId, stateSchema: { ... } }
js
await ridge.ready;
const stateSchema = ridge.getStateSchema();

Each value's schema is a JSON Schema draft 2020-12 fragment. Use it to validate host controls rather than guessing a component's accepted shape.

Suppress write notifications

Use a silent write when applying state already reflected in your host UI.

js
frame.contentWindow.postMessage(
  { type: "ridge:setState", state: values, silent: true },
  ridgeOrigin
);
js
await ridge.setState(values, { silent: true });

silent suppresses the change notification, not the write or its validation.

Initial state

Apply initial state before the dashboard becomes visible to avoid a flash of its default view.

text
Set the initial state in Ridge's embed playground and copy the resulting signed iframe URL.
The iframe reads its `state` URL parameter once when it mounts.
js
const ridge = await window.RidgeEmbed.load({
  jwt: token,
  dashboardId: "dashboard-id-123",
  rootElementId: "ridge-dashboard",
  state: { "region-menu": { filter: "EMEA" } }
});

Ridge AI