Skip to content

Inline embed quickstart

The inline embed mounts a dashboard directly into your page and returns a JavaScript handle. Authentication starts on your server; rendering happens in the browser inside a shadow root.

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 only `token` from your own authenticated endpoint.

See Inline authentication for the full credential flow and Partitioning before adding row-level restrictions.

2. Add a container and the loader

Load ridgeEmbedLoader.js from Ridge. The loader fetches the authenticated bundle and mounts it into a shadow root. This endpoint needs no credentials — the loader is what obtains the token-protected bundle, so it has to load before your JWT exists.

html
<div id="ridge-dashboard" style="min-height: 400px"></div>
<script src="https://app.ridgedata.ai/api/embed/loader"></script>

That serves the current loader. To pin a release instead, add ?v=:

html
<script src="https://app.ridgedata.ai/api/embed/loader?v=1.2.3"></script>

Pinned versions are immutable and cached for a year; the unpinned URL revalidates hourly, so fixes reach your page without a redeploy.

The loader is also a valid ES module if you prefer an explicit import, or if you would rather vendor the file into your own static assets:

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

Either form gives you the same RidgeEmbed object; the plain <script> tag above also sets it on window.

3. Fetch a JWT and mount

html
<script type="module">
  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 window.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());
</script>

load() resolves after the bundle has loaded and returns a stable handle. Attach listeners immediately, then await ridge.ready before synchronous reads. Writes wait for readiness internally.

Loader options

OptionRequiredDescription
jwtyesJWT returned by your backend.
dashboardIdyesPublished dashboard to render.
rootElementIdyesContainer element id.
apiBaseUrlnoDefaults to https://app.ridgedata.ai.
themenoPer-mount overrides; see Theming.
statenoInitial component state.
onErrornoCalled when the dashboard cannot load.

Cleanup

Call ridge.unmount() when a SPA removes the dashboard. This stops its listeners and queries rather than leaving them attached to a discarded route.

Ridge AI