https://github.com/metabase/metabase-nodejs-modular-embedding-sample
Modular Embedding Sample App
https://github.com/metabase/metabase-nodejs-modular-embedding-sample
Last synced: 2 months ago
JSON representation
Modular Embedding Sample App
- Host: GitHub
- URL: https://github.com/metabase/metabase-nodejs-modular-embedding-sample
- Owner: metabase
- License: mit
- Created: 2026-01-28T19:31:25.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-02-04T16:01:10.000Z (4 months ago)
- Last Synced: 2026-04-04T05:44:21.073Z (2 months ago)
- Language: JavaScript
- Homepage:
- Size: 37.1 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Metabase Embed.js Sample (Node.js + Express)
A minimal sample demonstrating Metabase embedding using **embed.js** with Node.js and Express. This sample shows how easy it is to integrate Metabase dashboards into your application without any frontend framework.
## Features
- **Single file setup** - Just `server.js` with Express
- **Guest Embed** - Anonymous access using signed JWT tokens
- **SSO Embed** - Authenticated user sessions with JWT SSO
- **No framework required** - Pure HTML with embed.js web components
## Prerequisites
- Node.js 18+
- Optionally Docker and Docker Compose (for running with a pre-configured Metabase instance)
- A Metabase Enterprise license
## Quick Start
### Running with Docker
1. Copy the environment file and add your Metabase license:
```bash
cp .env.docker.example .env.docker
# Edit .env.docker and add your MB_PREMIUM_EMBEDDING_TOKEN
```
2. Start the containers:
```bash
npm run docker:up
```
3. Open http://localhost:4400 in your browser
### Running locally with an existing Metabase instance
Before running, ensure your Metabase instance is configured following the [guest embedding setup guide](https://www.metabase.com/docs/latest/embedding/guest-embedding) and [SSO authentication guide](https://www.metabase.com/docs/latest/embedding/authentication).
1. Copy the environment file:
```bash
cp .env.example .env
# Edit .env with your Metabase instance URL, JWT secrets, and dashboard ID
```
2. Install dependencies and start the server:
```bash
npm install
npm start
```
3. Open http://localhost:3100 in your browser
## Project Structure
```
├── server.js # Express server with all routes
├── package.json # Dependencies
├── Dockerfile # Container build
├── docker-compose.yml # Docker orchestration
├── metabase/
│ └── config.yml # Metabase initial configuration
└── e2e/ # Cypress E2E tests
```
## How It Works
### Guest Embed (Signed JWT)
Guest embeds use signed JWT tokens to provide anonymous access to specific dashboards or questions. The server signs a token containing the resource ID and parameters, which is then passed to the `` component. See the [guest embedding docs](https://www.metabase.com/docs/latest/embedding/guest-embedding) for more details.
```javascript
// Server generates a signed token
const payload = {
resource: { dashboard: 1 },
params: {},
exp: Math.round(Date.now() / 1000) + 10 * 60,
};
const token = jwt.sign(payload, MB_EMBEDDING_SECRET_KEY);
```
```html
defineMetabaseConfig({
isGuest: true,
instanceUrl: "http://localhost:3000",
});
```
### SSO Embed (JWT Authentication)
SSO embeds authenticate users via JWT, creating a full user session in Metabase. The server returns a JWT containing user information when the embed.js client requests authentication. See the [authentication docs](https://www.metabase.com/docs/latest/embedding/authentication) for more details. This method enables end users to drill-through on charts, build their own visualizations, and ask questions to Metabase’s AI service. See a complete list of differences between SSO and guest embeds [in this doc](https://www.metabase.com/docs/latest/embedding/introduction#comparison-of-embedding-types).
```javascript
// Server returns user JWT at /auth/sso endpoint
const ssoPayload = {
email: "rene@example.com",
first_name: "Rene",
last_name: "Descartes",
groups: ["Customer"],
exp: Math.round(Date.now() / 1000) + 10 * 60,
};
const ssoToken = jwt.sign(ssoPayload, MB_JWT_SHARED_SECRET);
res.json({ jwt: ssoToken });
```
```html
defineMetabaseConfig({
instanceUrl: "http://localhost:3000",
jwtProviderUri: "http://localhost:3100/auth/sso",
});
```
## Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `PORT` | Server port | `3100` |
| `MB_INSTANCE_URL` | Metabase URL | `http://localhost:3000` |
| `MB_JWT_SHARED_SECRET` | JWT signing secret for SSO authentication | - |
| `MB_EMBEDDING_SECRET_KEY` | JWT signing secret for guest embeds | - |
| `MB_DASHBOARD_ID_TO_EMBED` | ID of the dashboard to embed | `1` |
| `MB_PREMIUM_EMBEDDING_TOKEN` | Metabase Enterprise license | - |
## Running E2E Tests
```bash
# Start Docker containers
npm run docker:up
# Run Cypress tests
cd e2e
npm install
npm run cypress:run
```
## License
This project is licensed under the MIT license. See the [LICENSE](./LICENSE) file for more info.