Security, Privacy, AI and CSR information for all Piano products now lives in one place. Explore our Compliance Center.
Subscriptions
English French
English French

Which variables from the JS tab can the JSX see, and how do I declare them?

LIGHTWEIGHT TEMPLATES

Everything declared at the top level of the JS tab, and nothing else. A nested scope, an IIFE, a callback, or a block is invisible to the markup, because the markup is compiled as a sibling statement of your top-level declarations, not inside them.

// ✅ visible to the JSX
let emailInput;                                   // let: the JSX assigns to it via ref
const [plan, setPlan] = createSignal("monthly");   // const is fine for a signal
const priceLabel = () => `${plan()} plan`;         // const is fine for a helper
// ❌ invisible to the JSX — wrapped in an IIFE
(function () {
  let emailInput;
})();
// ❌ invisible to the JSX — declared inside a named function.
// setup itself is visible; the variable inside it is not
function setup() {
  let emailInput;
}
setup();
// ❌ invisible to the JSX — declared inside a callback
onMount(() => {
  let emailInput;
});

Which keyword to use follows from what the JSX does with the name:

  • let or var - for anything the markup assigns to. That is ref, and only ref. const throws Assignment to constant variable at render time.

  • const - for everything the markup only reads: signals, memos, helper functions, plain constants.

Do not rely on an undeclared name. emailInput = el without a declaration creates a property on window, shared by every widget on the page; two instances of the same template will overwrite each other's element.

 

Last updated: