Embedding is available to all Lightdash Cloud users and Enterprise On-Prem customers. Get in touch to have this feature enabled in your account.
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.Benefits of iframe embedding
- Simple integration - Standard HTML iframe element, works anywhere
- No dependencies - No JavaScript libraries or SDK installation required
- No CORS configuration - Unlike the React SDK, iframes don’t require CORS setup
- Universal compatibility - Works in any web environment (React, Vue, Angular, vanilla HTML)
- Secure - JWT in URL hash fragment isn’t sent to server or logged
When to use iframe embedding
- Quick integration without adding dependencies
- Non-React applications
- Content management systems (WordPress, Webflow, etc.)
- Simple HTML pages or static sites
- When you don’t need programmatic control (filters, callbacks)
When to use React SDK instead
Consider the React SDK if you need:- Programmatic filters (apply filters via props)
- Callbacks (e.g., onExplore for analytics)
- Seamless React integration
- TypeScript type definitions
iframe URL patterns
All embed URLs follow this pattern:https://your-instance.lightdash.cloud/embed/{projectUuid}/{contentType}/{contentId}#{jwtToken}
The JWT is passed in the URL hash fragment (#token) for security—it’s not sent to the server in requests or logged in browser history.
Dashboard URL
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.
URL construction
Building the embed URL
- Get your project UUID - Found in Lightdash project settings
- Get dashboard ID - Dashboard UUID or slug
- Generate JWT - See embedding reference for token structure
- Construct URL - Combine parts with hash fragment
URL with user attributes
For row-level security, include user attributes in the JWT:Theming URL parameters
Embedded dashboards support two optional URL parameters for customizing the visual appearance of the embed. These are added as query parameters before the hash fragment.URL format
theme
Sets the color scheme for the embedded content.
| Value | Description |
|---|---|
light | Light color scheme (default) |
dark | Dark color scheme |
backgroundColor
Sets a custom background color on the embed. Accepts bare hex codes without the # prefix. The # is automatically prepended.
| Format | Example | Description |
|---|---|---|
| 6-digit hex | backgroundColor=121212 | Full hex color |
| 3-digit hex | backgroundColor=FFF | Shorthand hex |
| 8-digit hex | backgroundColor=FF000080 | Hex with alpha |
Combining both parameters
You can usetheme and backgroundColor together:
Both parameters are optional. Existing embed URLs without these parameters behave exactly as before — light theme with the default background.
Building themed URLs
Embedding in HTML
Basic iframe
The simplest way to embed is with a standard HTML iframe:Recommended attributes
width="100%"- Makes iframe responsive to container widthheight="600"- Fixed height (adjust based on content)frameborder="0"- Removes default border (legacy)style="border: none;"- Removes border (modern CSS)loading="lazy"- Defers loading until iframe is visibletitle="..."- Accessibility: Describes iframe content for screen readersallowfullscreen- Enables fullscreen mode (if your dashboard uses it)
Responsive iframes
To make iframes maintain aspect ratio and scale responsively: Method 1: Aspect ratio wrapper (16:9)Dynamic height
iframes have fixed height by default. For dynamic height based on content: Recommended approach for dashboards with unknown content:Security considerations
iframes provide natural security isolation, but you can add additional restrictions:allow-scripts- Required for Lightdash to functionallow-same-origin- Required for Lightdash to functionallow-forms- Required for filter interactionsallow-downloads- Required if you enable CSV/image exports
The
sandbox attribute provides additional security but may restrict functionality. Test thoroughly if you use it.Common patterns
Server-side rendering
Generate embed URLs in your server-side templates: Express (Node.js)Single-page apps (SPA)
Generate URLs via API when component mounts: React exampleStatic sites
For static sites, generate URLs at build time or use edge functions: Next.js (server component)Content management systems
Embed in WordPress, Webflow, or other CMS:- Create a server endpoint that generates embed URLs
- Use iframe embed code with dynamic URL
- Refresh tokens via JavaScript when expired
Token refresh
JWTs expire after the time specified inexpiresIn. Handle token expiration:
Option 1: Long-lived tokens
For public or semi-public dashboards, use longer expiration:Option 2: Regenerate URL on expiration
Detect when iframe shows “Token expired” error and reload with new URL:Option 3: Backend proxy
Create a backend endpoint that serves a static iframe URL but generates fresh tokens:Troubleshooting
Token not working
Issue: iframe shows “Invalid token” or “Token expired” Solutions:- Verify embed secret matches between token generation and Lightdash
- Check token hasn’t expired (
expiresInin jwt.sign) - Ensure JWT payload structure matches embedding reference
- Test token expiration:
jwt.decode(token)and checkexpfield
Content not displaying
Issue: iframe is blank or shows loading indefinitely Solutions:- Check browser console for errors
- Verify dashboard/chart UUID is correct
- Ensure content is added to “allowed dashboards/charts” in Lightdash settings
- Check project UUID is correct
- Try accessing embed URL directly in browser to see error message
CORS errors
Issue: Browser console shows CORS errors Solution:- iframes should NOT have CORS issues (CORS only affects React SDK)
- If you see CORS errors with iframes, you may be using fetch/XHR to load content instead of iframe
- Use standard iframe src attribute, not JavaScript-based loading
URL encoding issues
Issue: JWT or URL appears malformed Solutions:- Don’t URL-encode the JWT in the hash fragment
- If constructing URLs in templates, ensure proper escaping:
Dashboard filters not working
Issue: Users can’t interact with filters despitedashboardFiltersInteractivity: { enabled: 'all' }
Solutions:
- Verify JWT includes correct interactivity settings
- Check browser console for JavaScript errors
- Ensure iframe isn’t using
sandboxattribute withoutallow-forms
See also
Embedding reference
JWT structure and configuration options
React SDK reference
Alternative: React component embedding
Embedding dashboards
Step-by-step dashboard embedding guide
Embedding charts
Step-by-step chart embedding guide
User attributes
Row-level security with user attributes