Skip to main content
Version: 4.3

JSX to Markup

jsx() converts static JSX into the markup JSON format that JointJS expects. It is useful when you are defining native JointJS shapes, tool markup, markers, or other SVG structures that should exist as static JointJS markup rather than as React-rendered content.

Use renderElement when the node should be rendered by React at runtime. Use jsx() when you need static markup for a native JointJS definition.

When to use it​

  • Use jsx() for static JointJS markup
  • Use useMarkup() when selectors are registered inside renderElement
  • Use renderElement for dynamic React-rendered nodes and UI

Basic usage​

The most common pattern is defining a custom JointJS shape class and writing its markup in JSX instead of raw JSON.

This keeps the shape definition readable while still producing the exact static markup structure that JointJS expects.

What jsx() converts​

jsx() accepts a JSX element tree and returns JointJS MarkupJSON.

It supports:

  • normal SVG and HTML tag names
  • fragments
  • simple functional components used only for markup composition
  • joint-* attributes, which become top-level JointJS markup fields
  • className, which is converted to class
function Label() {
return (
<text
joint-selector="label"
x="80"
y="32"
textAnchor="middle"
dominantBaseline="middle"
/>
);
}

const markup = jsx(
<>
<rect joint-selector="body" width="160" height="64" className="task-body" />
<Label />
</>
);

That produces static markup. It does not create a live React component tree.

jsx() vs other React APIs​

These three APIs solve different problems:

  • jsx() writes static JointJS markup for native shapes, tools, and markers
  • useMarkup() registers named selectors inside a React-rendered element
  • renderElement renders the node itself with React at runtime

If the shape must be a native JointJS object with a markup field, jsx() is the right tool. If the node should be a live React-rendered component, stay with renderElement.

Constraints and notes​

  • jsx() is for static markup only
  • Do not use hooks, state, or context inside the JSX tree you pass to jsx()
  • Children must resolve to JSX elements, strings, numbers, booleans, or null
  • Plain functional components used only for markup composition are supported