Skip to content

feat(joint-react): SSR support for GraphProvider + release hardening#3338

Open
samuelgja wants to merge 2 commits into
clientIO:devfrom
samuelgja:feat/joint-react-ssr+prod-verification
Open

feat(joint-react): SSR support for GraphProvider + release hardening#3338
samuelgja wants to merge 2 commits into
clientIO:devfrom
samuelgja:feat/joint-react-ssr+prod-verification

Conversation

@samuelgja
Copy link
Copy Markdown
Contributor

@samuelgja samuelgja commented May 31, 2026

Description

Adds server-side rendering support to @joint/react and hardens the package for a stable release. Builds on the normalized paper-events work.

SSR

  • GraphProvider now renders on the server: it provides a synchronous, per-request GraphStore so children and data hooks (useCells, useGraph, …) render to HTML. The client path is unchanged (still created in a layout effect → StrictMode-safe).
  • GraphStore is SSR-safe: the element-size ResizeObserver falls back to a no-op when ResizeObserver is undefined (server), and uses the real one on the client.
  • useAreElementsMeasured provides a server snapshot (getServerSnapshot) so its useSyncExternalStore works during SSR.
  • Added useIsomorphicLayoutEffect (uses useEffect on the server) to avoid layout-effect SSR warnings.
  • <Paper> degrades gracefully to its host element on the server (the canvas is client-only) and mounts fully on the client.

Packaging / release hardening

  • Tightened package.json: sideEffects: ["**/*.css"] (keeps JS tree-shakeable while protecting the stylesheet), scoped files, removed the publish-blocking prepublishOnly, widened the React peer range to ^18 || ^19.
  • Restored the Storybook StrictMode decorator (it was a no-op).
  • Added CHANGELOG.md.

Tests

  • ssr.test.tsx — runs in a real Node (no-DOM) environment and verifies GraphProvider renders children + useCells data on the server, and Paper degrades without crashing.
  • ssr-client-handoff.test.tsx — hydrates a server-authored tree on the client and verifies the full interactive surface works after handoff: Paper mounts its real canvas, JointJS events fire, normalized event props invoke handlers, and React state updates re-render.

Motivation and Context

GraphProvider previously returned null until a layout effect ran, so the whole subtree was blank on the server — SSR/SSG produced no output for it. This makes GraphProvider (and any non-canvas UI that reads graph data) server-renderable, while keeping <Paper> correctly client-only. The packaging changes remove a publish blocker and prevent the stylesheet from being tree-shaken away.

Screenshots (if appropriate):

samuelgja added 2 commits May 30, 2026 18:49
…g across various examples

- Updated Paper component style properties to use single quotes for consistency.
- Replaced usePaperEvents with direct event handlers for onLinkMouseEnter, onLinkMouseLeave, onElementMouseEnter, and onElementMouseLeave in multiple examples.
- Added eslint-disable comments for performance-related rules in several files.
- Cleaned up unused imports and improved code readability in various components.
@samuelgja samuelgja requested a review from kumilingus May 31, 2026 07:58
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