Deployment
Embedding dashboards

Embedding Dashboards

Once you’ve published your dashboard in Embeddable, you can embed it in any website or web app - simply load our web component and pass in a security token.

How it works

Publish Your Dashboard

In the Embeddable builder, click Publish. This prepares the dashboard for embedding.

Insert Our Web Component

Add a <script> tag to your page to load the Embeddable custom element:

<script 
  type="module"
  src="https://embed.embeddable.com/js/v1/?region=<region>">
</script>

This makes the <em-beddable> tag available anywhere on your page.

Learn more about region here.

Place the <em-beddable> Element

Anywhere in your HTML, include:

<em-beddable
  token="eyJhbGciOiJIUzI1NiJ9..."
></em-beddable>

token is a security token from our Tokens API, which is used for row-level security and more.

Test Embedding

The quickest way to test embedding is to use our test script here.

Example: In a Plain HTML Page

<!DOCTYPE html>
<html>
  <head>
    <script 
      type="module"
      src="https://embed.embeddable.com/js/v1/?region=<region>">
    </script>
  </head>
  <body>
    <em-beddable 
      token="eyJhbGciOiJI..."
    ></em-beddable>
  </body>
</html>

Learn more about region here.

Learn how to retrieve a token here.


Embedding in a React App

If you’re using React, treat <em-beddable> like any other custom element. For example:

function Embeddable({ token }: { token: string }) {
  // Return a custom element
  return React.createElement('em-beddable', { token });
}
 
export default function DashboardPage() {
  const securityToken = 'eyJhbGciOiJI...'; 
  return <Embeddable token={securityToken} />;
}

Or using JSX directly:

export default function DashboardPage() {
  return (
    <>
      <script
        type="module"
        src="https://embed.embeddable.com/js/v1/?region=<region>"
      />
      <em-beddable
        token="eyJhbGciOiJI..."
      />
    </>
  );
}

Learn more about region here.

Learn how to retrieve a token here.

Using TypeScript

When embedding in TSX, you may get the following error:

Property 'em-beddable' does not exist on type 'JSX.IntrinsicElements'. ts(2339)

To fix this, you need to add a JSX element type declaration. You can either add this directly above a react component in the same file, or put it in a global types module.

declare module 'react' {
  namespace JSX {
    interface IntrinsicElements {
      'em-beddable': DetailedHTMLProps<
        HTMLAttributes<HTMLElement>,
        HTMLElement
      > & {
        token: string;
        variables?: string;
        'client-context'?: string;
      };
    }
  }
}

This code ensures the <em-beddable> tag is recognized by TypeScript, and that you get correct type-checking on its props.

Embedding in an Angular App

In Angular, you can use the <em-beddable> element in your templates. For example:

<em-beddable
  token=" eyJhbGciOiJI..."
></em-beddable>

Make sure you’ve loaded the script in your index.html (or another entry point) to define the custom element:

<script
  type="module"
  src="https://embed.embeddable.com/js/v1/?region=<region>">
</script>

Learn more about region here.

Learn how to generate a token here.

Angular by default sanitizes unknown attributes on elements, which can interfere with passing attributes to your embeddable (eg it may remove the client-context attribute). There are several ways to work around this, but we recommend either using Angular's DomSanitizer (opens in a new tab) to bypass security for the specific attributes you need, or creating a custom directive to handle setting the attributes on the <em-beddable> element, like this:

// App.ts
import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from '@angular/core';
import { RouterOutlet } from '@angular/router';
 
@Component({
  imports: [RouterOutlet],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  selector: 'app-root',
  templateUrl: './app.html',
})
export class App {
  /* Methods */
  protected readonly clientContext = signal(
    JSON.stringify({ theme: 'light' })
  );
}
<!-- app.html -->
<!-- ... -->
<em-beddable
  token="eyJhbGciOi..."
  [attr.client-context]="clientContext()"
  style="width: 100%">
</em-beddable>
<!-- ... -->

Embedding in a Vue App

In Vue, you can place <em-beddable> in your templates. For instance:

<template>
  <em-beddable
    :token="token"
  />
</template>
 
<script setup lang="ts">
import { ref, onMounted } from 'vue';
 
const token = ref('eyJhbGciOiJI...');
 
onMounted(() => {
  // Load the web component script if needed, or include in index.html
});
</script>

Make sure you’ve loaded the script in your index.html (or another entry point) to define the custom element:

<script 
  type="module"
  src="https://embed.embeddable.com/js/v1/?region=<region>">
</script>

Learn more about region here.

Learn how to generate a token here.

Vue by default sanitizes user input, which can interfere with passing attributes to your embeddable (eg it may remove values you're passing to the client-context attribute). To avoid this, Vue offers several methods to bind attributes safely (opens in a new tab).

Common Pitfalls

  • Security Token: Must be retrieved server-side to avoid exposing secrets. See our Tokens API docs.

  • Z-Index Issues: When embedding multiple dashboards on a single page, z-index conflicts can happen if the value isn't explicitly set. To resolve this, ensure that each <em-beddable> element has appropriate z-index settings and is set to position: relative. The Embeddables that appear higher on the page must have a higher z-index value than those that appear lower on the page, like in this example:

<div class="container">
  <!-- First dashboard with higher z-index -->
  <em-beddable token="..." style="position: relative; z-index: 2"></em-beddable>
  <!-- Second dashboard with lower z-index -->
  <em-beddable token="..." style="position: relative; z-index: 1"></em-beddable>
</div>

Complete Working Example

See our web-component-example repo (opens in a new tab) for a live demonstration, including how to fetch a security token from the Tokens API and embed it in a fully functional page or app.