YuriyKrasilnikov opened a new issue, #38336:
URL: https://github.com/apache/superset/issues/38336

   ### Is your feature request related to a problem?
   
   When embedding a Superset dashboard with a non-default theme, the current 
approach requires two post-initialization calls:
   
   ```ts
   const dashboard = await embedDashboard({ ... });
   
   dashboard.setThemeConfig({
     theme_default: { algorithm: 'default' },
     theme_dark: { algorithm: 'dark' },
   });
   
   setTimeout(() => {
     dashboard.setThemeMode('default');
   }, 0);
   ```
   
   This has several issues:
   - **Visual flash** — the iframe renders with the server default theme before 
receiving the config via MessageChannel
   - **Race condition** — `setTimeout(0)` doesn't guarantee `setThemeConfig` 
has been processed by the iframe
   - **Two separate messages** — unnecessary roundtrip for something that could 
be known at init time
   
   ### Proposed solution
   
   The iframe already defers rendering until it receives the `guestToken` 
message (`embedded/index.tsx:252-262`):
   
   ```ts
   let started = false;
   Switchboard.defineMethod('guestToken', ({ guestToken }) => {
     setupGuestClient(guestToken);
     if (!started) {
       start();       // render begins only here
       started = true;
     }
   });
   ```
   
   **Extend the handshake** to include theme config alongside `guestToken`, 
applying it before `start()`:
   
   #### SDK side (`superset-embedded-sdk/src/index.ts`):
   
   ```ts
   // New params in EmbedDashboardParams:
   initialThemeMode?: 'default' | 'dark' | 'system';
   initialThemeConfig?: Record<string, any>;
   
   // Send alongside guestToken:
   ourPort.emit('guestToken', {
     guestToken,
     themeMode: initialThemeMode,
     themeConfig: initialThemeConfig,
   });
   ```
   
   #### Iframe side (`superset-frontend/src/embedded/index.tsx`):
   
   ```ts
   Switchboard.defineMethod('guestToken', ({ guestToken, themeMode, themeConfig 
}) => {
     setupGuestClient(guestToken);
     if (themeConfig) themeController.setThemeConfig(themeConfig);
     if (themeMode) themeController.setThemeMode(themeMode);
     if (!started) {
       start();  // renders AFTER theme is applied — zero flash
       started = true;
     }
   });
   ```
   
   #### Usage:
   
   ```ts
   const dashboard = await embedDashboard({
     id: 'abc123',
     supersetDomain: 'https://superset.example.com',
     mountPoint: document.getElementById('dashboard'),
     fetchGuestToken: () => fetchToken(),
     initialThemeMode: 'dark',
     initialThemeConfig: {
       theme_default: { algorithm: 'default' },
       theme_dark: { algorithm: 'dark' },
     },
   });
   ```
   
   ### Why this works
   
   - **Zero flash** — theme is applied BEFORE first render, since `start()` is 
called after theme setup
   - **No URL encoding** — complex `themeConfig` objects travel through 
MessageChannel, not URL params
   - **Backward compatible** — `themeMode` and `themeConfig` are optional 
fields in the handshake; existing embeddings continue to work unchanged
   - **`setThemeConfig()` / `setThemeMode()` still available** — for runtime 
theme switching after initialization
   
   ### Additional context
   
   The key insight is that the iframe already has a natural "wait point" before 
first render — the `guestToken` handshake — which is the right place to pass 
any initial configuration.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to