Skip to content

metabase/modular-embedding-sample-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Metabase modular embedding example app

A sample app that shows two ways to embed Metabase dashboards:

  • SSO Embed - User is authenticated via your app. Metabase knows who they are. You get drill-through, permissions, the works.
  • Guest Embed - Anonymous access via signed JWT. No user identity passed to Metabase. You can do simple filtering.

What the app looks like

Requirements

Quick start

cp .env-template .env
# Edit .env with your keys (see below)
bun install
bun run index.ts

Open http://localhost:8080 to view the app. Use the tabs to switch between SSO and Guest embeds.

Configuration

1. Enable embedding in Metabase

Admin > Settings > Embedding > Enable Modular embedding

2. Get your secret keys

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

3. Configure .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 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 > Authorized origins: add http://localhost:8080

How it works

SSO Embed (/)

Browser → embed.js → /api/metabase/auth → 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/api/metabase/auth",
};

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);

API endpoints

Endpoint Purpose
/api/metabase/auth Returns JWT with user claims (SSO)
/api/metabase/guest-token Returns JWT with resource access (Guest)
/sso/metabase SSO endpoint for Metabase redirects

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: "user@example.com",
    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

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