Skip to content

experiment(notebooks): webapp Query editor as same-document widget#3473

Draft
mariusandra wants to merge 1 commit into
notebooks-in-codefrom
experiment/shared-widgets
Draft

experiment(notebooks): webapp Query editor as same-document widget#3473
mariusandra wants to merge 1 commit into
notebooks-in-codefrom
experiment/shared-widgets

Conversation

@mariusandra

@mariusandra mariusandra commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Experiment 3/3: shared widgets — the real insight editor in code, no iframe

Part of the notebook node-editing parity experiments (stacked on #3450). Companion posthog branch: code-widgets-experiment. Verdict from the run: keep / iterate.

Proves the toolbar pattern generalizes: the webapp's full editable Query/InsightViz editor (series row, math dropdown, full TaxonomicFilter, breakdown/filters) mounts same-document inside the code app — shadow root, its own React 18 + kea copy, coexisting with the React 19 tree with zero page errors — and round-trips query JSON to the host via onQueryChange.

What was verified

  • Standalone harness: editor fully styled and interactive inside the shadow root; popovers positioned correctly inside it; math change fired onQueryChange ("total""dau"); live dark/light flip restyles even open popovers.
  • Inside the running Electron app: mountQueryEditor next to the live React 19 UI, math change delivered "weekly_active" through the callback, clean unmount().
  • Not yet demonstrated: authenticated in-notebook editing (needs one interactive OAuth login in the experiment app instance; wiring is in place behind localStorage["posthog.notebooks.widgetsUrl"]).

Why it was cheap

Upstream already had the seams: standalone OAuth mode in lib/api.ts (one new in-memory setOAuthSessionOverride seam with a 401→refresh hook), FloatingContainerContext for popover containment, tokens declared on :root, :host. Only userLogic + teamLogic needed hand-mounting; everything else self-mounts via kea connect.

Numbers & findings

  • Bundle: widgets.js 2.03 MB (603 KB gz) + CSS 137 KB gz; eager mount cost ~2.7 MB gz total; 186 lazy chunks for deferred surfaces (monaco etc.).
  • CORS: non-issue — cloud allows all origins on /api/* (the toolbar depends on this).
  • Editor-critical endpoints (query, cohorts, event/property definitions, themes, user/org/team) all declare scope_object → token auth supported.

Dragons

kea-router listens to the host window.history (no interference observed; "open in app" links would misroute); kea's localStorage plugin writes into the host origin; Max AI conversations polling runs even embedded; production serving story (bundle in app resources vs cloud static) undecided.

🤖 Generated with Claude Code

Screenshots

The full TaxonomicFilter open inside the shadow root (dark theme), standalone harness:

Taxonomic filter in shadow root

Math dropdown, light theme — popovers positioned correctly inside the shadow root:

Math dropdown

Mounted inside the running Electron app next to the React 19 UI (widget bottom-right):

In-app mount

…dget

Wires the PostHog webapp's REAL insight editor (built as a standalone
widget bundle from the posthog repo's new frontend/src/widgets entry) in as
the EditComponent for notebook Query nodes. Same document, no iframe: the
bundle carries its own React 18 + kea and renders into a shadow root, the
toolbar pattern applied to the query editor.

- widgets/widgetLoader.ts: loads window.PostHogWidgets once via dynamic
  import; experiment toggle via localStorage key
  posthog.notebooks.widgetsUrl (e.g. http://localhost:8124/widgets.js).
- widgets/QueryWidgetEdit.tsx: EditComponent bridging node.props.query <->
  mountQueryEditor. Auth: apiHost from the auth store's cloud region,
  bearer tokens streamed through hostClient.auth.getValidAccessToken (also
  used as the widget's 401-refresh callback). Theme follows themeStore.
- notebookRegistry.tsx: Query nodes get the widget edit panel
  (exclusiveEditPanel) when the toggle is set; JSON editor otherwise.
- bootstrap.ts: POSTHOG_CODE_USERDATA_DIR override so a second dev
  instance can run side-by-side (single-instance lock lives in userData).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

React Doctor found 6 issues in 1 file · 3 errors & 3 warnings.

Errors

3 warnings

src/features/notebooks/widgets/QueryWidgetEdit.tsx

Reviewed by React Doctor for commit f73cbc9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant