We’ve migrated our documentation to a new site, which means some URLs have changed. If you hit a broken link, submit a support ticket.
Subscriptions
English French
English French

How does the JS tab interact with the JSX tab?

LIGHTWEIGHT TEMPLATES

They are not two separate files. Before the template reaches the browser, both tabs are compiled into a single component function: the JS tab becomes its body, the JSX tab becomes what it returns. Roughly this:

export default function execute(data) {
  const components = data.components;
  const html = data.components.html;
  const context = data.context;
  const dispatchSignal = data.dispatchSignal;
  const {
    batch, createEffect, createMemo, createResource, createSignal,
    mergeProps, onCleanup, onMount, splitProps, /* … */
  } = data.solidJs;
  function Custom() {
    // ─── everything from your JS tab is inlined here, verbatim ───
    return components.html`
      /* ─── your JSX tab, rewritten into a tagged template ─── */
    `;
  }
  return Custom;
}

Four consequences follow from that shape, and they explain most of the surprises in the questions below:

  • One scope. The JS tab and the JSX tab share the component's scope, so the JSX can read anything the JS tab declared at its top level — and nothing it declared deeper.

  • JS runs first, once per instance. The JS tab executes on every render of the widget, before the markup exists. A ref is therefore still empty while the JS tab runs.

  • No imports, ever. context, html, dispatchSignal and the Solid primitives (createSignal, createEffect, createMemo, onMount, …) are already in scope. Writing import in the JS tab is both unnecessary and a syntax error.

Component reference: Lightweight templates components. DOM handlers (onClick, onInput, …): Lightweight templates events.


Last updated: