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.
- Variables declared in the regular
<script>block. $context, in pages and components.$props, in components only.- Loop variables such as the item and the index, inside each iteration.
<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
- Arithmetic with
+,-,*,/and% - Comparison with
==,!=,===,!==,>,>=,<and<= - Logic with
&&,||,!and?? - Ternary, as in
condition ? valueA : valueB - Template literals, as in
`Hello ${name}` - Property and index access, as in
user.nameanditems[0] - Restricted method calls, as in
items.find((item) => ...)andname.trim()
Only these methods can be called.
- Array methods
find,some,map,filter,every,includesandreduce - String methods
includes,startsWith,endsWith,toLowerCase,toUpperCase,trimandslice
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>