fix: preserve widget state in HTML export - #8933
Conversation
Include session_view.ui_values in the HTML export serialization so widget states (dropdowns, sliders, plotly selections) are preserved instead of resetting to defaults. Changes: - Add ui_values field to NotebookSessionV1 schema (Python, YAML, TS) - Serialize ui_values in serialize_session_view() - Hydrate UI_ELEMENT_REGISTRY from ui_values in static mode (mount.tsx) The frontend hydration mirrors the existing pattern in handleKernelReady for live session reconnects (handlers.ts:162-166). Backward compatible: ui_values is Optional/nullable, so old HTML exports without it continue to work (widgets fall back to data-initial-value). Closes marimo-team#8613
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
I have read the CLA Document and I hereby sign the CLA |
|
All contributors have signed the CLA ✍️ ✅ |
|
Thanks @dmadisetti! Yes, still a draft — wanted to get the approach in front of you early rather than build out in isolation. The current change is intentionally minimal: serialize I stress-tested the edge cases from #8613:
That said, I expect there are dimensions I haven't considered — happy to hear what @peter-gy had in mind for propagating UI element values. If there's a broader approach this should fit into, I'm glad to adapt or pivot. Keeping as draft until we're aligned. |
|
This pull request has been automatically marked as stale because it has not had activity in 30 days. It will be closed in 14 days if no further activity occurs. If this PR is still relevant, please leave a comment or push new changes to keep it open. Thank you for your contribution! |
|
Still active. Before building this out further: @peter-gy, @dmadisetti mentioned you had an idea for propagating UI element values. Want to align on the hydration approach before I extend the draft. Current approach: serialize session_view.ui_values into the export HTML and hydrate UI_ELEMENT_REGISTRY before render. Can adapt if you have a different design in mind. |
|
Hi @dondetir! Thanks for exploring this! The approach looks pragmatic for this case, but we’re still working through the broader widget persistence story before committing to a direction in core. In the meantime, trrackpy by @kirangadhave (https://github.com/kirangadhave/trrackpy/blob/main/packages/trrack-widget/README.md?plain=1#L64-L83) may be worth a look for persisting widget state without changes to core marimo itself. |
|
Closing this for now while we work through the broader widget-persistence design. We’ll use this PR as a reference. |
This pull request was authored with assistance from a coding agent.
Summary
Preserve widget states (dropdowns, sliders, plotly selections) in HTML exports instead of resetting them to defaults.
Problem
When exporting a notebook as HTML via "Download as HTML (except code)", widget states reset to their construction-time defaults. A dropdown set to "Critical" exports as "Normal"; a chart filtered to 2 countries exports showing all countries. The reader sees something different from what the author intended to share.
Root cause:
session_view.ui_values(the dict tracking all widget interactions) is never included in the HTML export serialization.Solution
Three coordinated changes that mirror the existing live-session reconnect pattern (
handleKernelReadyinhandlers.ts:162-166):ui_values: Optional[dict[str, Any]]toNotebookSessionV1ui_values=dict(view.ui_values)inserialize_session_view()mount.tsx, readsession.ui_valuesand pre-populateUI_ELEMENT_REGISTRYbefore React renders widgets in static modeBackward compatible
ui_valuesisOptional/nullable with#[serde(default)]-equivalent behavior. Old HTML exports without the field continue to work (widgets fall back todata-initial-valueas before).Re: PII concern
Per @mscolnick's note — widget values are already visible in the rendered cell HTML output, so this doesn't expose new data. Happy to add a changelog entry noting this behavior change.
Files changed (10 files, +35/-8 lines)
marimo/_schemas/session.pyui_values: Optional[dict[str, Any]]marimo/_session/state/serialize.pyui_valuesin serializationmarimo/_schemas/generated/session.yamlpackages/openapi/src/session.tsfrontend/src/mount.tsxUI_ELEMENT_REGISTRYin static modetests/.../snapshots/*.json(5 files)Tests
Closes #8613