Expressions

Expressions render dynamic values in curly braces, in text and in attribute values, in pages and components alike. They are the main way to bind data into markup.

Expressions run in a safe subset of JavaScript, so some JavaScript features are left out by design.

How scope works

Every expression is evaluated against the current scope, the set of values available at that point in the template.

<script>
  const plans = [{ name: 'Starter' }, { name: 'Pro' }];
  const currency = 'EUR';
</script>

<li le-each="{plans as plan, i}">{i + 1}. {plan.name} ({currency})</li>

Here currency comes from the script, while plan and i come from the loop. For loop syntax, see Conditionals and Loops.

<script>
  const { title } = $props;
  const pagePath = $context.page;
  const label = title || 'Untitled';
</script>

<h1>{label}</h1>
<p>Current path: {pagePath}</p>

Only variable declarations in <script> reach the template, plus $editor.variants. Other statements, like function declarations or if blocks, are ignored, and a syntax error drops every variable in that script.

What $context and $props mean

$context holds data about the current page, like $context.page. The page and every component rendered in it can read it.

$props holds the values passed to one component instance, so the same component can render different content each time you use it. It exists only inside components.

Object Available in Typical use
$context Pages and components Read page-level values, like the current page path.
$props Components only Receive the attributes a component is used with.
$editor Pages and components, editor only Editor-only values isActive, variant and variants. See Editable Components.

$context example (page data)

<!-- Page file -->
<script>
  const currentPath = $context.page;
</script>
<small>{currentPath}</small>

$props example (component attributes)

<!-- Page usage -->
<Hero title="Build faster" ctaLabel="{primaryCta}" />

<!-- Hero.html -->
<script>
  const { title, ctaLabel } = $props;
</script>

Use expressions in text and attributes

Wrap any expression in {...}. The same syntax works in text content and in attribute values.

<script>
  const product = 'Starter';
  const price = 19;
  const slug = 'starter';
</script>

<h2>{product} plan</h2>
<p>From {price} €/month</p>
<a href="/pricing/{slug}">View details</a>

Always wrap attribute values in double quotes, expressions included. Write href="{url}", not href={url}.

Supported data types

Type Examples
String "hello", 'world'
Number 42, 3.14
Boolean true, false
Null values null, undefined
Array [1, 2, 3] (usually read with loops or indexing)
Object {label: "Pro", price: 19} (usually read through properties, like plan.name, not rendered whole)

Scope values should be plain data, meaning primitives, plain objects and plain arrays. Getters, setters, symbol keys and functions from outside the template are blocked.

Supported operators and syntax

Only these methods can be called.

A bare call like format(price) works only when format is an arrow function declared in the <script> block, as in const format = (p) => p + ' €';. Any other function call is refused.

Unsupported syntax

Templates do not support optional chaining, this, new, await, import(), tagged templates, update operators like count++, or sequence expressions.

Output behavior

An expression that returns null or undefined, or fails to evaluate, renders as an empty string. Text output is escaped, so it always renders as text, never as raw HTML.

Show braces literally

To display braces as plain text, for example in a code sample, put le-raw on the container element.

<pre le-raw><code>
<p>{title}</p>
</code></pre>

Next steps