Skip to content

Dashboard state ​

Dashboard state is an object keyed by component id. Each component has named values, such as filter. Iframe and JavaScript embeds use the same format:

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

In the iframe examples, replies and events are addressed to the origin of your first command after ridge:ready; see Host origin.

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

A JavaScript read before ridge.ready throws. For an iframe, wait for ridge:ready before sending requests. Match replies by requestId because your app may have several pending requests.

Write state ​

Updates merge by component id and state key. Values you omit stay unchanged. Set a value to null to clear it.

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; // complete state after rendering
result.changed; // component ids that changed
result.errors; // rejected component writes

The iframe does not send a response to ridge:setState. Listen for ridge:error to detect rejected updates. The JavaScript call returns the updated state and any errors after queries and rendering finish. Some updates in a batch may succeed while others fail.

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 values from your app's controls before sending them to the dashboard.

Suppress write notifications ​

Use silent when your app updates dashboard state and does not need a change notification.

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

With silent, updates are still validated and applied, but no change notification is sent.

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
import { RidgeEmbed } from "https://app.ridgedata.ai/api/embed/loader";

const ridge = await RidgeEmbed.load({
  jwt: token,
  dashboardId: "dashboard-id-123",
  rootElementId: "ridge-dashboard",
  state: { "region-menu": { filter: "EMEA" } }
});