---
url: https://docs.ridgedata.ai/guide/filters.md
---
# Filters

A filter is the `filter` key in a component's [state](./state). It controls which rows the component
displays within the embed's [partition](./partitioning).

Different components accept different filter shapes: a menu may take a scalar, a range may
take `[lo, hi]`, and a chart brush may take nested ranges. Use the state schema to
check which format a component accepts.

## Read filters

::: code-group

```js [Iframe]
const state = await getState(); // request ridge:getState; see Dashboard state
const filters = Object.fromEntries(
  Object.entries(state)
    .filter(([, values]) => "filter" in values)
    .map(([id, values]) => [id, values.filter])
);
```

```js [JavaScript]
await ridge.ready;
const filters = ridge.getFilters();
// { "region-menu": "EMEA", "date-range": ["2026-01-01", "2026-06-30"] }
```

:::

Components with no active filter are absent from the result.

## Set filters

::: code-group

```js [Iframe]
frame.contentWindow.postMessage(
  {
    type: "ridge:setState",
    state: { "region-menu": { filter: "APAC" } }
  },
  ridgeOrigin
);
```

```js [JavaScript]
const result = await ridge.setFilters({ "region-menu": "APAC" });
result.filters; // every active filter after the write
result.changed; // component ids that changed
result.errors; // rejected writes
```

:::

Set a filter to `null` to clear it. For iframes, read and update the `filter` key through
state messages. The JavaScript API also provides `getFilters()` and `setFilters()`.

## React to filter changes

::: code-group

```js [Iframe]
window.addEventListener("message", (event) => {
  if (event.source !== frame.contentWindow || event.origin !== ridgeOrigin) return;
  if (event.data?.type !== "ridge:stateChange") return;

  const filter = event.data.state["region-menu"]?.filter;
  syncRegionControl(filter);
});
```

```js [JavaScript]
ridge.on("filterchange", ({ filters, changes, source }) => {
  if (source === "user") syncMyControls(filters, changes);
});
```

:::

The JavaScript event distinguishes `"user"` from `"api"` changes. The iframe protocol sends
the resulting state. Use `silent` to update a filter without notifying your app of the change.

## Validate a value

::: code-group

```js [Iframe]
// Read `stateSchema` from ridge:ready or request ridge:getStateSchema.
const filterSchema = stateSchema["region-menu"]?.filter?.schema;
```

```js [JavaScript]
const filterSchema = ridge.getStateSchema()["region-menu"]?.filter?.schema;
```

:::

The returned value is a JSON Schema draft 2020-12 fragment. Use it to validate filter values.
A component's type or id alone does not tell you which values it accepts.
