Skip to content

metabase/modular-embedding-sample-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Metabase Modular Embedding - Sample app

Modular embedding sample app

Sample app for Modular embedding in Metabase. See the full SDK demo for what's possible. This app provides a minimal setup to understand each approach (you'll need to bring your own Metabase).

Requirements

Setup

1. Enable embedding in Metabase

Admin > Settings > Embedding > Enable Modular embedding

2. Get your secret keys

Embed Type Where to find the key
SSO + SDK Admin > Settings > Authentication > JWT > JWT signing key
Guest Admin > Settings > Embedding > Embedding secret key

3. Configure .env

Run:

cp .env-template .env

Then edit your .env :

METABASE_SECRET_KEY="your-jwt-signing-key"
METABASE_EMBEDDING_SECRET_KEY="your-embedding-secret-key"
METABASE_SITE_URL="http://localhost:3000"

4. Configure JWT authentication (for SSO/SDK embeds)

In Metabase (Admin > Settings > Authentication > JWT):

  • Set JWT Identity Provider URI to http://localhost:8080/sso/metabase .
  • Ensure the signing key matches METABASE_SECRET_KEY .

5. Add allowed origins

Admin > Settings > Embedding > Security > Authorized origins.

Add http://localhost:8080 (though localhost should be enabled by default).

6. Install and run the app

Install with:

bun install

Run with:

bun run start

Open http://localhost:8080 to view the app. Use the tabs to switch between the different types of embeds.

Embedding methods

Method Auth Use case
Guest Embed Signed JWT Anonymous view-only, locked to specific items
SSO Embed JWT SSO (user identity) Personalized dashboards, full Metabase features
React SDK JWT SSO (user identity) SSO features + plugins and custom actions

Project structure

├── index.ts                 # Server with auth endpoints
├── src/sdk-app.tsx          # React SDK app
├── public/
│   ├── index.html           # SSO Embed
│   ├── guest.html           # Guest Embed
│   ├── sdk.html             # React SDK
│   ├── theme-common.js      # Shared theme panel UI
│   ├── theme.js             # SSO config
│   └── guest-theme.js       # Guest config

API endpoints

  • GET /sso/metabase - JWT token for SSO/SDK (authenticated users)
  • GET /api/metabase/guest-token - Signed token for guest embedding

How it works

SSO Embed (/)

Browser → embed.js → /sso/metabase → JWT with user claims → Metabase

The <metabase-dashboard> component uses authProviderUri to fetch a JWT containing user info (email, name). Metabase auto-provisions the user on first login.

<metabase-dashboard dashboard-id="1" with-title="false"></metabase-dashboard>
window.metabaseConfig = {
  instanceUrl: "http://localhost:3000",
  authProviderUri: "http://localhost:8080/sso/metabase",
};

Guest Embed (/guest.html)

Browser → /api/metabase/guest-token → JWT with resource access → embed.js → Metabase

The token grants access to a specific dashboard without user identity. Your server signs tokens with the embedding secret key.

<metabase-dashboard
  with-title="true"
  with-downloads="true"
></metabase-dashboard>
window.metabaseConfig = {
  isGuest: true,
  instanceUrl: "http://localhost:3000",
};

// Fetch token from your backend, then:
dashboard.setAttribute("token", token);

React SDK (/sdk.html)

Browser → React app → fetchRequestToken → JWT with user claims → Metabase

The SDK provides React components with full interactivity. Uses the same JWT SSO auth as SSO Embed, but adds support for plugins and custom actions.

import {
  MetabaseProvider,
  InteractiveDashboard,
  defineMetabaseAuthConfig,
} from "@metabase/embedding-sdk-react";

const authConfig = defineMetabaseAuthConfig({
  metabaseInstanceUrl: "http://localhost:3000",
  fetchRequestToken: async () => {
    const response = await fetch("/sso/metabase");
    return await response.json();
  },
});

function App() {
  return (
    <MetabaseProvider authConfig={authConfig}>
      <InteractiveDashboard dashboardId={1} withTitle withDownloads />
    </MetabaseProvider>
  );
}

The SDK also supports plugins for custom click actions:

const pluginsConfig = {
  mapQuestionClickActions: (clickActions, clicked) => [
    ...clickActions,
    {
      name: "custom-action",
      title: "Custom action",
      icon: "star",
      onClick: ({ closePopover }) => {
        alert(`Clicked: ${clicked?.value}`);
        closePopover?.();
      },
    },
  ],
};

<MetabaseProvider authConfig={authConfig} pluginsConfig={pluginsConfig}>
  ...
</MetabaseProvider>;

Customization

Change the dashboard

Edit the dashboard-id attribute (SSO) or resource.dashboard in the token payload (Guest).

Change the authenticated user (SSO)

Edit the JWT claims in index.ts:

const token = jwt.sign(
  {
    email: "[email protected]",
    first_name: "First",
    last_name: "Last",
    exp: Math.floor(Date.now() / 1000) + 60 * 10,
  },
  METABASE_SECRET_KEY,
);

Theme customization

Click the Theme button to customize colors. Click Export theme to download as JSON.

Troubleshooting

Issue Solution
CORS errors Add http://localhost:8080 to allowed origins in Metabase
"Message corrupted" (Guest) Check METABASE_EMBEDDING_SECRET_KEY matches Metabase
JWT errors (SSO) Check METABASE_SECRET_KEY matches Metabase
Dashboard not found Verify dashboard ID exists and user has access

Development

bun run build   # Build SDK bundle only
bun run dev     # Run server (after build)
bun run start   # Build and run

Further reading

About

Small bun app to show how to wire up Embedded Analytics JS

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •