From 12dace3b8640b0446a160ffed2bfe260e4735ff1 Mon Sep 17 00:00:00 2001 From: "mintlify[bot]" <109931778+mintlify[bot]@users.noreply.github.com> Date: Mon, 15 Jun 2026 15:14:24 +0000 Subject: [PATCH] docs: document standalone data app embedding --- docs.json | 3 +- guides/embedding/data-apps.mdx | 120 ++++++++++++++++++++++ guides/embedding/how-to-embed-content.mdx | 18 +++- references/embedding.mdx | 63 +++++++++++- references/iframe-embedding.mdx | 19 +++- 5 files changed, 218 insertions(+), 5 deletions(-) create mode 100644 guides/embedding/data-apps.mdx diff --git a/docs.json b/docs.json index cca81c6b..ce3cce75 100644 --- a/docs.json +++ b/docs.json @@ -306,7 +306,8 @@ "group": "Embedding guides", "pages": [ "guides/embedding/dashboards", - "guides/embedding/charts" + "guides/embedding/charts", + "guides/embedding/data-apps" ] }, { diff --git a/guides/embedding/data-apps.mdx b/guides/embedding/data-apps.mdx new file mode 100644 index 00000000..ca348c81 --- /dev/null +++ b/guides/embedding/data-apps.mdx @@ -0,0 +1,120 @@ +--- +title: "How to embed data apps" +sidebarTitle: "Data apps" +description: "Embed a Lightdash data app as standalone content in an iframe using a JWT-scoped preview token." +--- + +import EmbedAvailability from '/snippets/embedding-availability.mdx'; + + + + + Standalone data app embedding is in early access and gated behind a feature flag. Contact Lightdash to enable it for your workspace. + + +## Overview + +Standalone data app embedding lets you render a [data app](/guides/data-apps) on its own — no dashboard, no surrounding chrome — inside an iframe in your application. The app runs in the same sandboxed environment as it does in Lightdash, with every metric query proxied through Lightdash and authorized against the embed JWT. + +Use standalone embedding when you want to surface an entire data app as a feature in your product (for example, a customer-facing report or interactive narrative) rather than embedding it as one tile on a Lightdash dashboard. + +### How it compares to other embed types + +| | Standalone data app | Data app tile on an embedded dashboard | Embedded chart | +|---|---|---|---| +| Content | One data app, full screen | One data app inside a dashboard | One saved chart | +| JWT `content.type` | `dataApp` | `dashboard` with `canViewDataApps: true` | `chart` | +| URL path | `/embed/{projectUuid}/app/{appUuid}` | `/embed/{projectUuid}` | React SDK only | +| Filters / tile chrome | None | Dashboard filters and tile chrome | None | + +For tile-based embedding inside a dashboard, see [View data apps in dashboards](/guides/embedding/dashboards#view-data-apps). + +## Setup + +### 1. Enable the data app in embed settings + +Open **Settings → Embedding** for your project and use the **Allowed content** section to authorize the data apps you want to embed: + +- Toggle **Allow all data apps** to permit any app in the project, or +- Add specific data apps to the allowlist. + +Standalone embedding is denied for any app that isn't on the allowlist (or covered by the "allow all" switch). This is enforced server-side regardless of what your JWT contains. + +### 2. Mint a data app JWT + +Sign a JWT with `content.type: 'dataApp'` and the `appUuid` of the data app you want to embed. The JWT must be signed with your project's embed secret. + +```javascript +import jwt from 'jsonwebtoken'; + +const token = jwt.sign( + { + content: { + type: 'dataApp', + projectUuid: 'your-project-uuid', + appUuid: 'your-app-uuid', + }, + user: { + externalId: 'user-123', + email: 'user@example.com', + }, + userAttributes: { + tenant_id: 'tenant-abc', + }, + }, + LIGHTDASH_EMBED_SECRET, + { expiresIn: '1h' }, +); +``` + +A `dataApp` token can only render the app named in its `appUuid` claim. It cannot be reused to render any other data app, chart, or dashboard. + +### 3. Construct the embed URL + +Data app embeds use the path `/embed/{projectUuid}/app/{appUuid}` with the JWT in the URL hash fragment: + +``` +https://your-instance.lightdash.cloud/embed/{projectUuid}/app/{appUuid}#{token} +``` + +The hash fragment is never sent to the server or stored in browser history. + +### 4. Render the iframe + +```html + +``` + +You can copy ready-to-use Node, Python, and Go snippets from **Settings → Embedding → Preview → Data apps** in Lightdash. + +## How access works + +A `dataApp` JWT is intentionally narrow: it authorizes the named app for the named project and nothing else. In practice, this means: + +- The token grants the embed user permission to **view the specified data app only**. +- The data app can run arbitrary metric queries across the project's tables. Embedding an app means you are accepting project-wide column access for that token. +- **Row-level filtering still applies.** User attributes on the JWT are enforced inside every query, just like they are for dashboard and chart embeds. SQL filters defined on your tables continue to apply. +- A `dataApp` token **cannot** be used to load dashboards, charts, or the explore page. Each embed token is scoped to a single content type. + + +Because the token grants project-wide column access for the app's queries, only mint `dataApp` tokens for audiences you trust with that data. Use [user attributes](/references/workspace/user-attributes) to enforce row-level access. + + +## Limitations + +- Standalone data app embedding is iframe-only. There is no React SDK component for it yet. +- The standalone embed has no filter bar or tile chrome — the app is rendered in isolation. +- Interactivity options like `canExportCsv`, `canExplore`, and `dashboardFiltersInteractivity` do not apply to `dataApp` tokens. + +## See also + +- [Data apps overview](/guides/data-apps) +- [Embedding reference (JWT structure)](/references/embedding) +- [iframe embedding reference](/references/iframe-embedding) +- [Embed dashboards with data app tiles](/guides/embedding/dashboards#view-data-apps) diff --git a/guides/embedding/how-to-embed-content.mdx b/guides/embedding/how-to-embed-content.mdx index 693f645e..7cad8234 100644 --- a/guides/embedding/how-to-embed-content.mdx +++ b/guides/embedding/how-to-embed-content.mdx @@ -12,7 +12,7 @@ import EmbedAvailability from '/snippets/embedding-availability.mdx'; ## What can you embed? -Lightdash supports embedding two types of content, each designed for different use cases: +Lightdash supports embedding three types of content, each designed for different use cases: ### Dashboards @@ -40,6 +40,17 @@ Chart embedding requires the React SDK. iframe embedding is only available for d [Learn more about embedding charts →](/guides/embedding/charts) +### Data apps + +Embed a [data app](/guides/data-apps) as standalone content in an iframe — the full app, no dashboard or surrounding chrome. Useful when you want to surface an entire AI-generated app as a feature in your product. + +**Use cases:** +- Customer-facing interactive reports +- Embedded narratives or slide-show apps in your product +- Self-serve analytics views built on your semantic layer + +[Learn more about embedding data apps →](/guides/embedding/data-apps) + ## How can you share or embed content? Lightdash offers three ways to share embedded content. The choice depends on whether you need to embed content in your own application or simply share a link. @@ -58,6 +69,7 @@ All three methods use the same JWT-based authentication and security model. |---|---|---|---| | Dashboards | ✓ | ✓ | ✓ | | Individual charts | ✗ | ✗ | ✓ | +| Data apps (standalone) | ✓ | ✓ | ✗ | | Requires embedding in an app | No | Yes | Yes | | Setup complexity | Low | Low | Medium | | CORS needed | No | No | Yes | @@ -154,6 +166,10 @@ Lightdash provides code snippets you can copy and use in your app to generate va Learn how to embed individual charts for focused displays + + Embed a standalone data app in an iframe, no dashboard required + + Show different data to different users with user attributes diff --git a/references/embedding.mdx b/references/embedding.mdx index 165f7b48..709cadb7 100644 --- a/references/embedding.mdx +++ b/references/embedding.mdx @@ -31,7 +31,7 @@ Embedded Lightdash content is available to view by anyone (not just folks with a ## Known limitations -- Embedding only works for dashboards and charts directly. To embed explores, use the `canExplore` flag in a dashboard. +- Embedding works for dashboards, charts, and [data apps](/guides/data-apps). To embed explores, use the `canExplore` flag in a dashboard. - The **Filter dashboard to** option when clicking on individual chart segments will not work on embedded dashboards. If you're interested in embedding and one or more of these items are blockers, please reach out. @@ -239,6 +239,67 @@ const token = jwt.sign({ }, SECRET, { expiresIn: '24h' }); ``` +### Data app token + +For embedding a [data app](/guides/data-apps) as standalone content in an iframe (no dashboard). See [How to embed data apps](/guides/embedding/data-apps) for the full guide. + +```typescript +{ + content: { + type: 'dataApp', + + // Data app identifier (required) + appUuid: string, + + // Project identifier (optional) + projectUuid?: string, + + // Preview mode (optional) + isPreview?: boolean, + }, + + // Optional: User information for query tracking + user?: { + externalId?: string, + email?: string, + }, + + // Optional: User attributes for row-level filtering + userAttributes?: { + [attributeName: string]: string, + }, +} +``` + + +A `dataApp` token authorizes only the named app. It cannot render any other data app, chart, or dashboard, even if that content is on the embed allowlist. Interactivity options like `canExportCsv`, `canExplore`, and `dashboardFiltersInteractivity` do not apply to `dataApp` tokens. + + + +A data app can run arbitrary metric queries across the project. Minting a `dataApp` token means accepting project-wide column access for the app's queries. Row-level access via [user attributes](/references/workspace/user-attributes) is unchanged. + + +**Example:** + +```javascript +import jwt from 'jsonwebtoken'; + +const token = jwt.sign({ + content: { + type: 'dataApp', + projectUuid: 'your-project-uuid', + appUuid: 'your-app-uuid', + }, + user: { + externalId: 'user-789', + email: 'user@example.com', + }, + userAttributes: { + tenant_id: 'tenant-abc', + }, +}, SECRET, { expiresIn: '1h' }); +``` + ## Interactivity options reference ### Dashboard filters interactivity diff --git a/references/iframe-embedding.mdx b/references/iframe-embedding.mdx index f5d107d1..7a9d1408 100644 --- a/references/iframe-embedding.mdx +++ b/references/iframe-embedding.mdx @@ -10,10 +10,10 @@ import EmbedAvailability from '/snippets/embedding-availability.mdx'; ## Overview -iframe embedding is the simplest way to embed Lightdash **dashboards** in your application. It requires no special libraries, dependencies, or CORS configuration—just generate a JWT and construct an embed URL. +iframe embedding is the simplest way to embed Lightdash **dashboards** and standalone **data apps** in your application. It requires no special libraries, dependencies, or CORS configuration—just generate a JWT and construct an embed URL. -iframe embedding is **only available for dashboards**. Chart embedding requires the [React SDK](/references/react-sdk). +iframe embedding supports dashboards and [data apps](/guides/embedding/data-apps). Chart embedding requires the [React SDK](/references/react-sdk). ### Benefits of iframe embedding @@ -61,6 +61,21 @@ The `dashboardUuid` is specified inside the JWT payload as `content.dashboardUui https://app.lightdash.cloud/embed/abc-123-def-456#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` +### Data app URL + +Standalone [data app](/guides/embedding/data-apps) embeds put both the project UUID and the app UUID in the path: + +``` +https://your-instance.lightdash.cloud/embed/{projectUuid}/app/{appUuid}#{jwtToken} +``` + +The JWT must use `content.type: 'dataApp'` and the same `appUuid` as the URL. A token for one app cannot render any other app. + +**Example:** +``` +https://app.lightdash.cloud/embed/abc-123-def-456/app/app-uuid-789#eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... +``` + The JWT in the hash fragment is NOT sent to the server with HTTP requests and does NOT appear in server logs or browser history, providing an additional security layer.