Skip to content

JavaScript embed quickstart ​

Load a dashboard in your page with the Embed SDK's JavaScript embed. Your server creates an access token, and the browser loads the dashboard inside a shadow root. The returned object provides methods for controlling the dashboard.

1. Create a token endpoint ​

Your backend exchanges a Ridge API key for a dashboard-scoped JWT. Never send the API key to the browser.

js
// Your server, after authenticating the current user.
const response = await fetch("https://app.ridgedata.ai/api/embed/token", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RIDGE_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({ dashboardIds: ["dashboard-id-123"] })
});

if (!response.ok) throw new Error("Could not create a Ridge embed token");
const { token } = await response.json();

// Return { token } as JSON from your own authenticated endpoint.

See JavaScript authentication for authentication details and Partitioning before adding row-level restrictions.

2. Add a container ​

html
<div id="ridge-dashboard" style="min-height: 400px"></div>

3. Import the loader, fetch a JWT, and mount ​

Import the loader from /api/embed/loader inside a module script. A classic <script src="..."> cannot parse the loader's ES module exports.

The loader is public and contains no customer data. It loads the JavaScript and CSS needed for the dashboard and sends the JWT with its requests. Dashboard and data access require a valid credential; downloading JavaScript or CSS alone does not grant access to either.

Place this script after the container:

html
<script type="module">
  import { RidgeEmbed } from "https://app.ridgedata.ai/api/embed/loader";

  try {
    const tokenResponse = await fetch("/api/ridge-token", { credentials: "same-origin" });
    if (!tokenResponse.ok) throw new Error("Could not authorize dashboard");
    const { token } = await tokenResponse.json();

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

    ridge.on("statechange", ({ state }) => console.log(state));
    await ridge.ready;
    console.log(ridge.getState());
  } catch (error) {
    console.error("Could not load the Ridge dashboard", error);
  }
</script>

/api/ridge-token is the endpoint you create in step 1, on your app's server. It returns { "token": "...", "expiresIn": 86400 }. The Ridge endpoint that accepts your API key is the absolute URL https://app.ridgedata.ai/api/embed/token; call it only from your server.

load() returns the dashboard handle once the bundle has loaded. Attach listeners before awaiting ridge.ready and before updating filters. Wait for ready before reading state or schemas. Methods that update state wait for readiness automatically.

Loader options ​

These options belong to RidgeEmbed.load(). The separate EmbedOptions type describes the lower-level embed() function, which takes a dashboard URL and an HTML element directly.

OptionRequiredDescription
jwtyesToken returned by your backend.
expiresInwith getTokenLifetime of jwt in seconds, as returned with it by POST /api/embed/token.
getTokennoFunction () => Promise<{ token, expiresIn }> that returns a new token from your backend, so the embed outlives jwt. Return the POST /api/embed/token response body. Mint each with the same sessionId; see Expiry and refresh.
dashboardIdyesPublished dashboard id allowed by the token.
rootElementIdyesId of a container element already present in the document.
apiBaseUrlnoDefaults to https://app.ridgedata.ai.
themenoTheme overrides for this embed; see Theming.
statenoObject keyed by component id, then state key, for example { "region-menu": { filter: "EMEA" } }. See Dashboard state.
onErrornoCallback (error: Error) => void for errors reported during bundle initialization or dashboard loading. It does not receive every possible failure; use try/catch around load() and ready as shown above.

Loading errors ​

load() throws synchronously if jwt, dashboardId, or rootElementId is missing, or the container cannot be found. These validation errors do not call onError. Bundle fetch errors reject the returned promise and also bypass onError. Dashboard loading errors can reject ridge.ready. A try/catch around both awaited calls handles these cases.

Loader versions and caching ​

The unversioned URL serves the current loader. Use its response's Cache-Control header to check how long a browser may cache it; do not depend on an hourly refresh interval.

?v=<published-version> requests a stored loader version. Only use a version confirmed as published by Ridge. An unavailable version returns 404; 1.2.3 is not a verified release. Pinning the loader does not pin the dashboard bundle: the current loader requests the unversioned JavaScript and CSS bundle URLs.

Cleanup ​

Call ridge.unmount() when your app removes the dashboard, such as when navigating to another page. This stops the dashboard's listeners and queries.