The rules
What a custom template can and can't do — and the single most common mistake.
Your template is one JSX expression — the thing you'd put after return ( in a React component. Nothing more.
Allowed
- Any JSX elements and attributes
props.anything.map(), ternaries (cond ? a : b),&&, string concatenation, arithmetic- Inline arrow functions in event handlers:
onClick={() => props.onAddToKit()} React.Fragment, or the<>…</>shorthand- Inline
style={{ … }}objects
Not allowed
import/require— you have no access to other files- Hooks (
useState,useEffect, …) — the template holds no state - Statements:
const x = …,if (…) { … },return …,function … fetch,window, timers, or any other browser API- Multiple top-level elements without a wrapper — wrap them in
<>…</>
If you need a value that isn't in props, that's a gap in what the app provides, not something to work around. Contact support and ask for it.
The single most common mistake
Every value you need has to be computed inline, inside { }, because the whole template is one expression with no room for a line that assigns to a variable first.
Two syntax notes
classisclassName. Write<div className="my-card">, notclass.- Styles are objects with camelCase keys.
style={{ backgroundColor: "red", fontSize: "14px" }}, not a CSS string.
Why the restrictions exist
Every rule here traces back to the same guarantee: a template can only lay out pixels, never touch the data layer. That's what makes a mistake harmless — a compile error is caught before anything reaches your store, and a runtime error falls back to the built-in design instead of breaking the page. See Troubleshooting for what each kind of failure looks like and how to fix it.
Next
CSS variables and styling — keep your Design-tab settings working inside your custom markup.