Supported Expression Types

Template expressions can contain any JavaScript expression that is valid in a template context. This topic enumerates and provides a wide range of examples of supported expression types. For some restrictions on expressions in an HTML template, see HTML Syntax Compatibility.

Literals 

All JavaScript literal types are supported in template expressions.

String Literals 

While you don’t need an expression to display a simple string in a template, string literals can be useful when composing user interface messages. See Template Literals.

1<template>
2  <div>{'Hello World'}</div>
3</template>

Numeric Literals 

All numeric literal formats are supported:

1<template>
2  <!-- Integer literals -->
3  <div>{42}</div>
4
5  <!-- Float literals -->
6  <div>{42.42}</div>
7
8  <!-- Binary literals -->
9  <div>{0b1001011}</div>
10
11  <!-- Octal literals -->
12  <div>{0o42}</div>
13
14  <!-- Hexadecimal literals -->
15  <div>{0x42}</div>
16
17  <!-- Exponentiation -->
18  <div>{2 ** 3}</div>
19</template>

Boolean Literals 

1<template>
2  <div>{true}</div>
3  <div>{false}</div>
4</template>

Null Literal 

1<template>
2  <div>{null}</div>
3</template>

Template Literals 

Template literals allow you to embed expressions inside string literals using ${} syntax.

1<template>
2  <div>{`User: ${firstName} ${lastName}`}</div>
3  <div>{`Status: ${isActive ? 'Active' : 'Inactive'}`}</div>
4  <div>{`Price: $${price.toFixed(2)}`}</div>
5</template>
1import { LightningElement } from "lwc";
2
3export default class TemplateLiteralsComponent extends LightningElement {
4  firstName = "John";
5  lastName = "Doe";
6  isActive = true;
7  price = 99.99;
8}

Tagged template literals are also supported:

1<template>
2  <div>{formatCurrency`Total: ${amount}`}</div>
3</template>
1import { LightningElement } from "lwc";
2
3export default class TaggedTemplateComponent extends LightningElement {
4  amount = 100;
5
6  formatCurrency(strings, amount) {
7    return `$${amount.toFixed(2)}`;
8  }
9}

See Tagged Templates at MDN for additional details regarding tagged template literals.

Being too adventurous with tagged templates can lead to hard-to-understand template markup. Template expressions are intended to simplify your code. Take advantage of it.

Note

Identifiers and Member Expressions 

Direct property access and member expressions are fully supported.

1<template>
2  <div>{ hello().world }</div>
3  <div>{ anotherWorld.sayHello() }</div>
4</template>
1import { LightningElement } from "lwc";
2
3export default class IdentifiersComponent extends LightningElement {
4  hello() {
5    return {
6      world: "Hi there!",
7    };
8  }
9
10  anotherWorld = {
11    sayHello: () => "Hello from a function!",
12  };
13}

Ternary Operators 

Conditional expressions using the ternary operator (? :) for dynamic content.

1<template>
2  <div>{isLoggedIn ? 'Welcome back!' : 'Please log in'}</div>
3  <div>{age >= 18 ? 'Adult' : 'Minor'}</div>
4
5  <!-- Compact form without spaces -->
6  <div>{darkMode?nowItsDark:seeTheLight}</div>
7
8  <!-- Nested ternary -->
9  <div>{score > 80 ? 'Excellent' : score > 60 ? 'Good' : 'Needs Improvement'}</div>
10</template>
1import { LightningElement } from "lwc";
2
3export default class TernaryComponent extends LightningElement {
4  isLoggedIn = true;
5  age = 25;
6  score = 75;
7  darkMode = true;
8  nowItsDark = "Dark value";
9  seeTheLight = "Light value";
10}

Logical Operators 

Logical AND (&&) and OR (||) operators for conditional rendering and fallback values.

1<template>
2  <div>{user && user.name}</div>
3  <div>{error || 'No error occurred'}</div>
4  <div>{isValid && isSubmitted && 'Form submitted successfully'}</div>
5</template>
1import { LightningElement } from "lwc";
2
3export default class LogicalOperatorsComponent extends LightningElement {
4  user = { name: "John Doe" };
5  error = null;
6  isValid = true;
7  isSubmitted = true;
8}

Unary Operators 

Various unary operators are supported.

Logical NOT 

1<template>
2  <div>{!foo}</div>
3</template>
1import { LightningElement } from "lwc";
2
3export default class LogicalNotComponent extends LightningElement {
4  foo = true;
5}

Bitwise NOT 

1<template>
2  <div>{~foo}</div>
3  <div>{~bar}</div>
4</template>
1import { LightningElement } from "lwc";
2
3export default class BitwiseNotComponent extends LightningElement {
4  foo = 5;
5  bar = 10;
6}

typeof Operator 

1<template>
2  <div>{typeof foo}</div>
3</template>
1import { LightningElement } from "lwc";
2
3export default class TypeofComponent extends LightningElement {
4  foo = "test";
5}

void Operator 

1<template>
2  <div>{void bar}</div>
3</template>
1import { LightningElement } from "lwc";
2
3export default class VoidComponent extends LightningElement {
4  bar = "value";
5}

Binary Operators 

All binary operators are supported for various operations.

Arithmetic Operators 

1<template>
2  <div>{high + low}</div>
3  <div>{high - low}</div>
4  <div>{high * low}</div>
5  <div>{high / low}</div>
6  <div>{high ** low}</div>
7</template>
1import { LightningElement } from "lwc";
2
3export default class ArithmeticComponent extends LightningElement {
4  high = 10;
5  low = 3;
6}

Relational Operators 

1<template>
2  <div>{big > little}</div>
3  <div>{little > big}</div>
4  <div>{big >= little}</div>
5  <div>{big === little}</div>
6  <div>{big !== little}</div>
7</template>
1import { LightningElement } from "lwc";
2
3export default class RelationalComponent extends LightningElement {
4  big = 10;
5  little = 5;
6}

Expressions must be HTML compliant because they are parsed as HTML. The “<” character in text node expressions like {foo < bar} would be interpreted as the opening of an HTML tag, causing a parsing error. However, < is allowed in attribute expressions when properly quoted.

  • In text nodes: Use {bar > foo} instead of {foo < bar}
  • In attributes: {foo < bar} works when quoted: attr="{foo < bar}"

See HTML Syntax Compatibility for additional details.

Important

Bitwise Operators 

1<template>
2  <div>{foo & bar}</div>
3  <div>{foo | bar}</div>
4  <div>{foo ^ bar}</div>
5  <div>{foo >> bar}</div>
6  <div>{bar >> foo}</div>
7  <div>{bar >>> foo}</div>
8</template>
1import { LightningElement } from "lwc";
2
3export default class BitwiseComponent extends LightningElement {
4  foo = 12; // 1100 in binary
5  bar = 5; // 0101 in binary
6}

Function Calls 

Call methods and functions directly in templates.

Put your formatting functions in a separate API module component that you can easily import into any component that use them.

Tip

1<template>
2  <div>{formatCurrency(price)}</div>
3  <div>{getFullName(firstName, lastName)}</div>
4  <div>{items.map(item => item.name).join(', ')}</div>
5</template>
1import { LightningElement } from "lwc";
2
3export default class FunctionCallsComponent extends LightningElement {
4  price = 99.99;
5  firstName = "John";
6  lastName = "Doe";
7  items = [{ name: "Item 1" }, { name: "Item 2" }, { name: "Item 3" }];
8
9  formatCurrency(price) {
10    return `$${price.toFixed(2)}`;
11  }
12
13  getFullName(first, last) {
14    return `${first} ${last}`;
15  }
16}

Optional Call Expressions 

Optional chaining for function calls is supported.

1<template>
2  <div>{foo?.(bar)}</div>
3  <div>{baz?.buzz?.(42)}</div>
4</template>
1import { LightningElement } from "lwc";
2
3export default class OptionalCallComponent extends LightningElement {
4  bar = "test";
5
6  connectedCallback() {
7    this.foo = (value) => `Called with: ${value}`;
8    this.baz = {
9      buzz: (value) => `Buzz called with: ${value}`,
10    };
11  }
12}

Array Expressions 

Create and manipulate arrays inline.

1<template>
2  <div>{[firstName, lastName].join(' ')}</div>
3  <div>{items.length > 0 ? `Found ${items.length} items` : 'No items'}</div>
4  <div>{[1, 2, 3, 4, 5].reduce((a, b) => a + b, 0)}</div>
5  <div>{[1, bar, 'baz']}</div>
6  <div>{['flop', floo, 2].join('')}</div>
7</template>
1import { LightningElement } from "lwc";
2
3export default class ArrayExpressionsComponent extends LightningElement {
4  firstName = "John";
5  lastName = "Doe";
6  items = ["item1", "item2", "item3"];
7  bar = "bar value";
8  floo = "floo value";
9}

Object Expressions 

Create object literals and access their properties.

1<template>
2  <div>{({ name: 'John', age: 30 }).name}</div>
3  <div>{({ status: 'active' }).status}</div>
4</template>

Optional Chaining and Nullish Coalescing 

Safe property access, and null and undefined handling.

1<template>
2  <div>{user?.profile?.name ?? 'Anonymous'}</div>
3  <div>{settings?.theme || 'default'}</div>
4  <div>{data?.items?.length ?? 0}</div>
5</template>
1import { LightningElement } from "lwc";
2
3export default class OptionalChainingComponent extends LightningElement {
4  user = {
5    profile: {
6      name: "John Doe",
7    },
8  };
9  settings = { theme: "dark" };
10  data = { items: [1, 2, 3] };
11}

Computed Properties 

Dynamic property access using bracket notation.

1<template>
2  <div>{user['firstName']}</div>
3  <div>{items[selectedIndex]}</div>
4  <div>{config[`${prefix}Setting`]}</div>
5  <div>{bar.baz.arr[quux]}</div>
6  <div>{bar.arr[baz.quux]}</div>
7</template>
1import { LightningElement } from "lwc";
2
3export default class ComputedPropertiesComponent extends LightningElement {
4  user = { firstName: "John" };
5  items = ["item1", "item2", "item3"];
6  selectedIndex = 1;
7  config = { mySetting: "value" };
8  prefix = "my";
9  bar = {
10    arr: ["a", "b", "c"],
11    baz: {
12      arr: ["x", "y", "z"],
13    },
14  };
15  baz = { quux: 0 };
16  quux = 2;
17}

Arrow Functions 

Arrow functions can be used for inline transformations and callbacks.

1<template>
2  <div>{items.map(item => item.name.toUpperCase())}</div>
3  <div>{numbers.filter(n => n > 10).length}</div>
4  <div>{users.find(user => user.id === currentId)?.name}</div>
5</template>
1import { LightningElement } from "lwc";
2
3export default class ArrowFunctionsComponent extends LightningElement {
4  items = [{ name: "apple" }, { name: "banana" }, { name: "cherry" }];
5  numbers = [5, 15, 25, 35];
6  users = [
7    { id: 1, name: "Alice" },
8    { id: 2, name: "Bob" },
9    { id: 3, name: "Charlie" },
10  ];
11  currentId = 2;
12}

Assignment Inside Arrow Functions 

Assignment operations are allowed inside arrow functions.

1<template>
2  <button onclick="{() => myField = 'foo'}">Set Label</button>
3  <button onclick="{() => foo++}">Increment Foo</button>
4  <div>Field: {myField}</div>
5  <div>Foo: {foo}</div>
6</template>
1import { LightningElement } from "lwc";
2
3export default class AssignmentComponent extends LightningElement {
4  myField = "";
5  foo = 0;
6}

Iterator Support 

Expressions work within iterator directives.

1<template>
2  <template for:each="{getBentoItems()}" for:item="okazu">
3    <div key="{okazu}">
4      <a onclick="{() => taberu(okazu)}">
5        one
6      </a>
7    </div>
8  </template>
9</template>
1import { LightningElement } from "lwc";
2
3export default class IteratorComponent extends LightningElement {
4  allItems = ["sushi", "tempura", "miso", "ramen"];
5
6  getBentoItems() {
7    return this.allItems.filter((item) => item !== "ramen");
8  }
9
10  taberu(item) {
11    alert(`Eating ${item}`);
12  }
13}

See Example: Render Lists with Template Expressions for an extended example and discussion of using iterators in template expressions.

LWC Directive Compatibility 

Complex expressions work with LWC directives like if:true.

1<template>
2  <template if:true="{state.isTrue && user?.isActive}">
3    {foo} {bar}
4  </template>
5</template>
1import { LightningElement } from "lwc";
2
3export default class DirectiveComponent extends LightningElement {
4  state = { isTrue: true };
5  user = { isActive: true };
6  foo = "foo value";
7  bar = "bar value";
8}