Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically Styling Embedded Dashboards #32357

Open
Gilks opened this issue Feb 23, 2025 · 3 comments
Open

Dynamically Styling Embedded Dashboards #32357

Gilks opened this issue Feb 23, 2025 · 3 comments
Labels
global:theming Related to theming Superset

Comments

@Gilks
Copy link

Gilks commented Feb 23, 2025

Context

I'm embedding dashboards into my SaaS. My SaaS has a toggle that users can selected that swaps from light to dark mode.

Problem

For security reasons, you cannot interact with an iframe from a different origin. This means you're unable to directly modify the CSS within the embedded iframe. While it is possible to add CSS directly to each dashboard in SuperSet- this is not ideal as it leads to an administrative nightmare.

Question

Is it possible to initialize a dashboard with specific CSS? It would be nice if you could pass in props like this. This would allow the SaaS to dictate what the theme settings should be when the dashboard is loaded:

await embedDashboard({
  id: selectedDashboardData.uuid || selectedDashboardData.id,
  supersetDomain: process.env.REACT_APP_SUPERSET_DOMAIN,
  mountPoint: dashboardRef.current,
  fetchGuestToken: () => supersetToken,
  dashboardUiConfig: {
    hideTitle: true,
    hideTab: true,
    hideChartControls: true,
    cssTemplate: `
      .dashboard {
        background-color: red !important;
      }
    `
  }
});
Copy link

dosubot bot commented Feb 23, 2025

Hey there, @Gilks! I'm here to assist with any bugs, questions, and help you become a contributor. Let's tackle this together! 🤖

I found a similar unsolved discussion titled Embedded dashboard does not use parent document preferred color scheme which might be relevant to your situation [1].

Regarding your question, the Superset embedding API does support passing custom UI configuration options when initializing a dashboard, as indicated by a change log entry that mentions adding optional dashboard UI configuration [2]. However, there is no specific mention of passing custom CSS directly through the API.

For injecting custom CSS into dashboards, Superset provides a mechanism through the injectCustomCss function. This function allows you to apply custom CSS to dashboards by creating a <style> element and appending it to the document's <head>. This approach can be used to dynamically manage styles, although it might require some additional handling to work with embedded dashboards [3][4].

To continue talking to Dosu, mention @dosu.


Help Dosu learn! Give it feedback: Great Response | Irrelevant Answer | Incorrect Sources | Too Verbose | Hallucination | Bug Report | Other

@dosubot dosubot bot added the global:theming Related to theming Superset label Feb 23, 2025
@rusackas
Copy link
Member

I would strongly advise against passing CSS through the iframe wall... CSS is good for some tweaks/overrides, but there is a whole vision (a SIP and a PR soon to merge) that are working toward proper systemic theming in Superset. When we get there, I'd be fine with passing a theme name/ID as a parameter, and/or revisiting the concept of passing CSS through as well, but for now, passing a big CSS palyoad into the iframe is risky business, and will probably be an anti-pattern when we have proper theming support (finally).

@Gilks
Copy link
Author

Gilks commented Feb 24, 2025

I agree that it's not an ideal to style through the iframe boundry. In a perfect world, we would have the solution as you described. However, it's also difficult to fully integrate and utilize embedded dashboards without the ability to dynamically control themes. In theory we could manage the CSS themes directly in superset but that would mean creating duplicate dashboards in light/dark mode and creating the code required to manage context switching. It also means reloading iframes when switching themes- not an ideal user experience.

As a stop gap, I've created a custom postMessage() handler that is initialized through superset_config.py. It is very much a hack and I look forward to being able to style as you described. The goal was to create something self contained that can survive superset upgrades.

It allows something like this:

const embeddedFrame = document.querySelector('iframe');
embeddedFrame.contentWindow.postMessage({
    switchboardAction: 'emit',
    method: 'customCss',
    args: {
        css: '.dashboard { background: blue !important; }'
    }
}, '*');

I can post the complete solution if you'd like. I just don't want to push anyone down this path if a more robust solution is in the works. If you think it would be beneficial in the meantime, let me know and I'll post the hack.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
global:theming Related to theming Superset
Projects
None yet
Development

No branches or pull requests

2 participants