+
+
+## Embedding with React SDK
+
+Chart embedding requires the Lightdash React SDK for seamless integration in your React application.
+
+
+
+
+Alternatively, toggle "Allow all dashboards" to enable embedding for any dashboard in your project.
+
+## Configuring interactivity
+
+Control what users can do with your embedded dashboard by configuring interactivity options. These options work for both iframe and React SDK embedding methods and are set in the JWT token.
+
+While the SDK options are configured via React props, iframe options are configured in the admin UI where you setup the embedding:
+
+
+
+
+
+### Dashboard filters
+
+Dashboard filters allow users to slice and filter data across all charts in the dashboard. You can control whether users can interact with these filters, which filters they can modify, and whether the filter UI is visible.
+
+**Configure in JWT token:**
+
+```javascript
+{
+ content: {
+ type: 'dashboard',
+ dashboardUuid: 'your-dashboard-uuid',
+ dashboardFiltersInteractivity: {
+ enabled: 'all', // 'all', 'some', or 'none'
+ },
+ }
+}
+```
+
+**Options:**
+- `'all'` - All dashboard filters are interactive and visible
+- `'some'` - Only specified filters are interactive (use `allowedFilters` array)
+- `'none'` - Filters are applied but not visible or editable
+
+**Allow specific filters only:**
+
+```javascript
+{
+ content: {
+ type: 'dashboard',
+ dashboardUuid: 'your-dashboard-uuid',
+ dashboardFiltersInteractivity: {
+ enabled: 'some',
+ allowedFilters: ['filter-uuid-1', 'filter-uuid-2'],
+ },
+ }
+}
+```
+
+**Hide filter UI:**
+
+```javascript
+{
+ dashboardFiltersInteractivity: {
+ enabled: 'all',
+ hidden: true, // Filters work but UI is hidden
+ }
+}
+```
+
+### Parameters
+
+Parameters are dynamic values that can be referenced in your queries and filters. When enabled, users can modify parameter values to change what data is displayed across the dashboard.
+
+**Configure in JWT token:**
+
+```javascript
+{
+ content: {
+ type: 'dashboard',
+ dashboardUuid: 'your-dashboard-uuid',
+ parameterInteractivity: {
+ enabled: true,
+ },
+ }
+}
+```
+
+### Export options
+
+Allow users to export data and visualizations from the embedded dashboard. You can control which export formats are available.
+
+**Configure in JWT token:**
+
+```javascript
+{
+ content: {
+ type: 'dashboard',
+ dashboardUuid: 'your-dashboard-uuid',
+ canExportCsv: true, // Export chart data as CSV
+ canExportImages: true, // Export charts as PNG/images
+ canExportPagePdf: true, // Export entire dashboard page as PDF
+ }
+}
+```
+
+**Available export options:**
+- **CSV** - Download raw data from individual charts
+- **Images** - Export charts as PNG images
+- **PDF** - Export the entire dashboard page as a PDF document
+
+### Date zoom
+
+Date zoom allows users to dynamically change the time granularity of time-series visualizations (e.g., view by day, week, month, quarter, year) without modifying the underlying query.
+
+**Configure in JWT token:**
+
+```javascript
+{
+ content: {
+ type: 'dashboard',
+ dashboardUuid: 'your-dashboard-uuid',
+ canDateZoom: true,
+ }
+}
+```
+
+### Explore from here
+
+"Explore from here" allows users to navigate from a dashboard chart into the full query builder interface, where they can modify dimensions, metrics, filters, and create ad-hoc analyses starting from the chart's configuration.
+
+**Configure in JWT token:**
+
+```javascript
+{
+ content: {
+ type: 'dashboard',
+ dashboardUuid: 'your-dashboard-uuid',
+ canExplore: true,
+ }
+}
+```
+
+When enabled, users see an "Explore from here" option on chart tiles that opens the explore interface.
+
+### View underlying data
+
+View underlying data shows users the raw data table behind any visualization, making it easy to inspect the actual values and records that create the chart.
+
+**Configure in JWT token:**
+
+```javascript
+{
+ content: {
+ type: 'dashboard',
+ dashboardUuid: 'your-dashboard-uuid',
+ canViewUnderlyingData: true,
+ }
+}
+```
+
+### Complete configuration example
+
+```javascript
+import jwt from 'jsonwebtoken';
+
+const token = jwt.sign({
+ content: {
+ type: 'dashboard',
+ projectUuid: 'your-project-uuid',
+ dashboardUuid: 'your-dashboard-uuid',
+
+ // Filter controls
+ dashboardFiltersInteractivity: {
+ enabled: 'all',
+ },
+
+ // Parameter controls
+ parameterInteractivity: {
+ enabled: true,
+ },
+
+ // Export capabilities
+ canExportCsv: true,
+ canExportImages: true,
+ canExportPagePdf: true,
+
+ // Interactive features
+ canDateZoom: true,
+ canExplore: true,
+ canViewUnderlyingData: true,
+ },
+
+ // User information (for analytics)
+ user: {
+ externalId: 'user-123',
+ email: 'user@example.com',
+ },
+
+ // User attributes (for row-level filtering)
+ userAttributes: {
+ tenant_id: 'tenant-abc',
+ },
+}, LIGHTDASH_EMBED_SECRET, { expiresIn: '1h' });
+```
+
+## iframe embedding
+
+iframe embedding is the simplest way to embed dashboards. No special libraries or dependencies required.
+
+### URL structure
+
+```
+https://your-instance.lightdash.cloud/embed/{projectUuid}/dashboard/{dashboardUuid}#{jwtToken}
+```
+
+Or using dashboard slug:
+
+```
+https://your-instance.lightdash.cloud/embed/{projectUuid}/dashboard/{dashboardSlug}#{jwtToken}
+```
+
+The JWT token is passed in the URL hash fragment for security.
+
+### Generate JWT token
+
+
-
You can regenerate the secret by clicking on the `Generate new secret` button. If you do this, people with an old URL will automatically lose access to any previously shared embed URL.
-### Allowed dashboards
+### Step 2: Add allowed dashboards
-Only selected dashboards can be accessed via embed URLs
+Only selected dashboards can be accessed via embed URLs. Add the dashboard you want to embed to the allowed list.
+### Step 3: Configure and preview
-### Preview
-
-Under preview you can generate a one-off shareable embed URL for a single dashboard.
+Under the "Configure" section, you can:
+- Select which dashboard to embed
+- Set token expiration time
+- Configure interactivity (filters, exports, etc.)
+- Add user attributes for row-level security
-Click on `preview` to see the embed content and click on `Generate & copy URL` to generate an embed URL for this dashboard
+Click on `Preview` to see how the embedded content will look, and click on `Generate & copy URL` to get a one-off embed URL for testing.
-### Developer flow and code snippet
+### Step 4: Generate tokens programmatically
-Although you can generate URLs directly from Lightdash with a long expiration it is recommended to generate your own JWT tokens in your backend with a short expiration using your `secret`to make sure people can't be using embed URLs outside your app.
+Although you can generate URLs directly from Lightdash with a long expiration, it is recommended to generate your own JWT tokens in your backend with a short expiration using your `secret` to make sure people can't be using embed URLs outside your app.
-To make this easier to integrate, we included some code snippets you can copy and use in your app to generate a valid embed URL
+Lightdash provides code snippets you can copy and use in your app to generate valid embed URLs:
-
-
-
-### Filter the tables used in your dashboard with `sql_filter`
-
-We need to filter the access to all of the tables we use in our dashboard using this attribute. For example, in my `Order Summary` dashboard, I use the `orders` and the `shops` tables to build all of the charts. So, in these two tables, I'm going to add a [row-level filter](#../references/user-attributes#1-row-filtering-with-sql%5Ffilter) using my `shop_id` attribute, like:
-
-```yaml
-models:
- - name: orders
- meta:
- sql_filter: ${lightdash.attributes.shop_id} = 'all' OR ${TABLE}.shop_id = ${lightdash.attributes.shop_id}
-```
+No, embedded Lightdash content is available to view by anyone (not just folks with a Lightdash login).
-### Add the user attribute to your dashboard embed
+So, for example, you could embed a dashboard in your product, and anyone who has access to your product would have access to that dashboard. No need to login to Lightdash.
-Now that we have our user attribute set up and filtering our data properly, we want to head back to our dashboard embedding configuration.
+We make sure that the links are secure and have a set expiry time that you pick.
-There are two ways to use user attributes in your embedded dashboard:
+### How does security work?
-**Option 1: assign a constant value for your attribute**
+Embedded content is secured using JWT (JSON Web Tokens) that you sign with your embed secret. The token includes:
-You can assign your dashboard a single, constant value for your attribute by adding it in the `user attributes` section of your embedded dashboard setup.
+- What content to display (dashboard or chart)
+- Expiration time
+- User attributes for row-level filtering
+- Permissions for interactivity (filters, exports, etc.)
-For example, if I wanted the embed link to only show data for `shop_id = Thyme to Shine`, then I would add a user attribute `shop_id` with the value `Thyme to Shine`.
+Tokens are short-lived and should be generated server-side to prevent exposure of your embed secret.
-
-
-
+### Can I show different data to different users?
-**Option 2: assign a variable value for your attribute**
-
-You can adjust the value of the user attribute based on a variable coming from your app so, for example, the user attribute for `shop_id` in the Lightdash embedded dashboard would change depending on which `shop_id` the user belonged to in my app.
-
-To do this, I would pass Lightdash an external value for `shop_id` in the embed code snippet. This could look something like:
-
-```yaml
-import jwt from 'jsonwebtoken';
-const LIGHTDASH_EMBED_SECRET = 'secret'; // replace with your secret
-const projectUuid = '21eef0b9-5bae-40f3-851e-9554588e71a6';
-const userShopId = await getUserShopIdFromDatabase();
-const data = {
- content: {
- type: 'dashboard',
- dashboardUuid: 'a392ed6d-4c53-4102-89b7-1c57a87df391',
- },
- userAttributes: { shop_id: userShopId },
-};
-const token = jwt.sign(data, LIGHTDASH_EMBED_SECRET, { expiresIn: '1 hour' });
-const url = `https://analytics.lightdash.cloud/embed/${projectUuid}/#${token}`;
-```
-
-And voila! you now have an embedded dashboard that shows different values for different users in your app.
+Yes! You can use [user attributes](/references/user-attributes) to implement row-level security in your embedded content. This allows you to filter data based on the viewing user's properties (e.g., tenant ID, region, etc.).
diff --git a/images/guides/embed-add-chart.png b/images/guides/embed-add-chart.png
new file mode 100644
index 0000000..d0565ee
Binary files /dev/null and b/images/guides/embed-add-chart.png differ
diff --git a/images/guides/embed-iframe-interactivity.png b/images/guides/embed-iframe-interactivity.png
new file mode 100644
index 0000000..a67027f
Binary files /dev/null and b/images/guides/embed-iframe-interactivity.png differ
diff --git a/references/embedding.mdx b/references/embedding.mdx
index 31a97cc..e6376c1 100644
--- a/references/embedding.mdx
+++ b/references/embedding.mdx
@@ -1,215 +1,714 @@
---
title: "Embedding reference"
-description: "You can embed Lightdash content in your website or application securely using Lightdash embedding."
+description: "Complete API reference for embedding Lightdash content securely using JWT tokens"
---
-