These are the docs for the Metabase master branch. Some features documented here may not yet be available in the current release. Check out the docs for the current stable version, Metabase v0.57.

Modular embedding

Modular embedding with SSO is only available on Pro and Enterprise plans (both self-hosted and on Metabase Cloud).

Modular embedding wizard

Modular embedding lets you embed and customize Metabase components (like dashboards, the query builder, AI chat, and more) into your own application. You don’t need to write embedding code on your own - just use the wizard to create a code snippet and paste it into your app.

If you’re using React, check out the Modular embedding SDK.

Enable modular embedding

  1. In Metabase, go to Admin settings > Embedding.
  2. Toggle on Enable modular embedding.
  3. Under Cross-Origin Resource Sharing (CORS), add the URLs of the websites where you want to embed Metabase (such as https://*.example.com). For testing embeds, you can use localhost which is always included in CORS policy.
  4. If you’re embedding Metabase components in a domain that’s different from your Metabase’s domain (including when you’re testing the app locally but use Metabase Cloud), go to Admin settings > Embedding > Security and set SameSite cookie to None.

Create a new embed

In your Metabase:

  1. Visit the item you want to embed.
  2. Click the sharing icon.
  3. Select Embed.

Embed share button

You can also open a command palette with Ctrl/Cmd+K, type “New embed”. You’ll get a wizard to help you set up your embed.

You can also go to Admin settings > Embedding > Modular embedding and click New embed.

New modular embed from the admin settings

Pick how to authenticate the embed

How you authenticate the embed determines how cool the embed can get. This page covers the SSO setup, which lets you do everything. This setup requires you to have set up SSO for your Metabase. You can check out a comparison between SSO and guest, or jump straight to the guest embed docs. But we recommend setting up modular embedding with SSO.

Customize your embed

The exact customization options you see will depend on what type of entity you’re embedding. You’ll see a live preview of the embed with your customizations.

Embed flow options for AI chat

You’ll also be able to pick colors for:

  • Brand
  • Text
  • Background

But you can customize a lot more later. To configure other colors (like secondary colors, query builder colors, and more), as well as font, you can specify a theme in your embed code snippet.

All the customization options you select in this interactive flow will be reflected in code snippet, which you can edit as you see fit.

For example, this code defines the font, color, and size for text, background colors, and colors for filters and summaries:

<script>
  defineMetabaseConfig({
    instanceUrl: "https://your-metabase-url",
    theme: {
      fontFamily: "Lato",
      fontSize: "16px",
      colors: {
        background: "#11123d",
        "text-primary": "#f9f9fc",
        brand: "#50e397",
        filter: "#7172AD",
        summarize: "#88BF4D",
      },
    },
  });
</script>

For more look-and-feel twiddling, see appearance.

Once you’re done customizing your embed, click Next.

Add the embedding script to your app

Metabase will generate a code snippet that you can copy and paste into your app. See the example below. You can later modify this code snippet to specify additional appearance options or change the behavior of some components.

You’ll add this code snippet to your app and refresh the page.

The code snippets:

  • Loading the modular embedding library from your Metabase instance.
  • Set global configuration settings, like the URL of your Metabase and the theme. See Page-level config.
  • The component(s) to embed, with their parameters. See Components.

Here’s an example snippet:

<!-- Load embedding library -->
<!-- REPLACE WITH YOUR METABASE URL HERE -->

<script defer src="https://your-metabase-url/app/embed.js"></script>

<script>
  function defineMetabaseConfig(config) {
    window.metabaseConfig = config;
  }
</script>

<!-- Embedding configuration -->
<script>
  defineMetabaseConfig({
    instanceUrl: "https://your-metabase-url",
    theme: {
      colors: {
        background: "#ffffff",
      },
    },
  });
</script>

<!--Embedded entities -->
<metabase-question question-id="1"></metabase-question>

<metabase-dashboard dashboard-id="2" with-title="false"></metabase-dashboard>

Note the defer attribute and the reference to your Metabase URL in the script that loads embed.js library.

If you’re embedding multiple components in a single page, you only need to include the <script> tags once globally.

Each end user should have their own Metabase account

With SSO embeds, each end-user must have their own Metabase account.

The problem with having end-users share a Metabase account is that, even if you filter data on the client side via the modular embedding, all end-users will still have access to the session token, which they could use to access Metabase directly via the API to get data they’re not supposed to see.

If each end-user has their own Metabase account, however, you can configure permissions in Metabase and everyone will only have access to the data they should.

In addition to this, we consider shared accounts to be unfair usage. Fair usage of modular embedding involves giving each end-user of the embedded analytics their own Metabase account.

Customizing embeds

The exact customization options you see will depend on what type of entity you’re embedding.

When you’re creating a new embed using Admin > Embedding > Setup guide > Embed in your code, you’ll see the following customization options in the interactive creation flow. These options correspond to parameters in components.

  • Allow people to drill through on data points: determines whether people can interact with the chart (or charts on a dashboard). Interactivity includes drilling down to individual records from aggregated questions, filtering on click, zooming in, etc. Disabling drill-through for an embedded question also disables people’s ability to add filters and summaries.

  • Allow downloads: determines whether people can download question results and save dashboards as PDFs.

  • Allow people to save new questions. If you embed the query builder but disable this option, people can still do their own explorations, they just won’t be able to save them.

  • Parameters: for dashboard filters, SQL variables, and time grouping parameters, you can add default values. Default values set here override the default values set at the dashboard or question level. For dashboard filters and parameters, you can choose whether to hide the parameter.

  • Show title: what it says on the tin.

  • Allow editing dashboards and questions: lets people create and edit dashboards or questions in the current collection. When disabled, they can still perform actions like filter, summarize, and drill-through, but won’t be able to save results.

Page-level config

To define the configuration that applies to every embed on the page, use the defineMetabaseConfig() function. Its parameters include:

  • instanceUrl: "https://your-metabase-url" (required): the URL of your Metabase instance, like https://youlooknicetoday.metabaseapp.com

  • theme: {...} (optional): appearance options for the embeds.

  • useExistingUserSession: true|false (optional, for development only) - lets you preview the embed locally using your Metabase admin account session. Only supported in Google Chrome.

  • apiKey: mb_YourAPIKey (optional, for development only) - another way to preview embeds locally using an API key.

  • fetchRequestToken: () => Promise<{ jwt: string }> (optional) - you can customize how the SDK fetches the refresh token for JWT authentication by specifying the fetchRequestToken function. See customizing JWT authentication.

Authentication

Use API keys to test embeds

API keys can only be used for testing embeds locally. To make your embeds production-ready or deploy them to another domain, you’ll need to implement SSO.

To use an API key to test your embeds:

  1. Create an API key
  2. Add apiKey: "YOUR_API_KEY" to defineMetabaseConfig():
<script>
  defineMetabaseConfig({
    instanceUrl: "https://your-metabase-url",
    apiKey: "mb_hopeyouhaveaniceday",
  });
</script>

API keys should only be used for testing with trusted people. Anyone with access to the front-end can grab the API key and use it to make requests against the Metabase API. For this reason, we only allow using API keys on localhost.

Embedding Metabase in a different domain

If you want to embed Metabase in another domain (say, if Metabase is hosted at metabase.yourcompany.com, but you want to embed Metabase at yourcompany.github.io), you can tell Metabase to set the session cookie’s SameSite value to “none”.

You can set session cookie’s SameSite value in Admin settings > Embedding > Security > SameSite cookie setting.

SameSite values include:

  • Lax (default): Allows Metabase session cookies to be shared on the same domain. Used for production instances on the same domain.
  • None (requires HTTPS): Use “None” when your app and Metabase are hosted on different domains. Incompatible with Safari and iOS-based browsers.
  • Strict (not recommended): Does not allow Metabase session cookies to be shared with embedded instances. Use this if you do not want to enable session sharing with embedding.

You can also set the MB_SESSION_COOKIE_SAMESITE environment variable.

If you’re using Safari, you’ll need to allow cross-site tracking. Depending on the browser, you may also run into issues when viewing embedded items in private/incognito tabs.

Learn more about SameSite cookies.

Setting up SSO

For production use, you’ll need to set up SSO authentication. See Modular embedding - authentication for details on setting up JWT or SAML authentication.

Example app with SSO embed and theming

Check out our sample app. Bring your Metabase, embed a dashboard, and play around with changing colors.

Read docs for other versions of Metabase.

Was this helpful?

Thanks for your feedback!
Want to improve these docs? Propose a change.