HTML Templates

A component that renders UI has an HTML template file and a JavaScript class file.

The power of Lightning Web Components is the templating system, which uses the virtual DOM to render components smartly and efficiently. Use simple syntax to declaratively bind a component’s template to data in the component’s JavaScript class.

A template is valid HTML with a <template> root tag. Write templates using standard HTML and a few directives that are unique to Lightning Web Components. Directives are special HTML attributes, like if:true and for:each, that give you more power to manipulate the DOM in markup.

Let Lightning Web Components manipulate the DOM instead of writing JavaScript to do it.

Data Binding

To bind a property in a component’s template to a property in the component’s JavaScript class, in the template, surround the property with curly braces: {property}.

Here’s the simplest example of data binding. The name property in the template is bound to the name property in the JavaScript class.

In helloWorld.js, change the value of World! and you'll see the component update.

To see the power of data binding, add another property in helloWorld.js.

@api announcement = 'I\'m coding web components.';

In helloWorld.html, add {announcement}.

The property in { } must be a valid JavaScript identifier or member expression. For example, {data} and {data.name} are both valid. Don’t add spaces around the property, for example, { data } is not valid HTML. It's illegal to compute a value in an expression, like data[2].name['John']. To compute a value, use a getter.

The @api decorator makes the name property public so that other components can set it. If we remove @api, the property still binds to the HTML template, but it's private. To see for yourself, remove @api in the playground. When the value of name changes, the component re-renders.

This code is standard HTML and JavaScript. The only feature in this code that’s exclusive to Lightning Web Components is the @api decorator.

Handle User Input

This component has an input field that asks for a name to greet. When the value of the input field changes, the component changes the value of the bound name property.

Type something in the input field to see the recipe in action.

The <input> element uses the oninput event to listen for a change to its value. To bind the handleInput function to the template, we use the same syntax that we use to bind a property, {...}. The handleInput JavaScript function executes when the value of the <input> element changes.

When the value of the name property changes, the component re-renders.

We talk about event handling in-depth in another topic, but notice in helloBinding.js that handleInput is passed an event object. The event object contains information about the input event. The component uses the event object to get the value that the user enters into the input field.

Note

In LWC versions 1.1.0 and higher, properties that contain a primitive value are reactive. If a reactive property is used in a template and its value changes, the component re-renders.

Use Getters to Compute a Value

To dynamically compute a value for a property used in a template, define a JavaScript getter that computes the value.

<template>
    {propertyName}
</template>
import { LightningElement } from 'lwc';
export default class Component extends LightningElement {
    get propertyName() {
        // Compute a value for propertyName
     }
}

Getters are much more powerful than computing values in template expressions because they’re JavaScript functions and can contain any code that's legal in a function. Getters also enable unit testing, which reduces bugs and the pain of debugging.

When a component renders, all the expressions used in the template are evaluated, which means that getters are invoked.

This example takes two variables, firstName and lastName, concatenates them, and converts them to uppercase.

Render Lists

To render a list of items, use for:each directive or the iterator directive to iterate over an array.

The iterator directive has first and last properties that let you apply special behaviors to the first and last items in an array.

Regardless of which directive you use, you must use a key directive to assign a unique ID to each item. When a list changes, the framework uses the key to re-render only the item that changed. The key in the template is used for performance optimization and isn’t reflected in the DOM at run time.

This code you write to render lists is standard HTML and JavaScript, except for the directives, which are exclusive to Lightning Web Components.

for:each

To render an array, add the for:each={array} directive to a nested <template> tag that encloses the HTML elements you want to repeat. To access the current item, use for:item="currentItem". To access the current item’s index, use for:index="index".

Every item in a list must have a key. To assign a key to every element in the list, use the key={uniqueId} directive.

This example iterates over an array called contacts, which is defined in the component’s JavaScript class.

Important

Every item in a list must have a key. When a list changes, the framework uses the key to identify each item so that it can re-render only the item that changed. The key must be a string or a number, it can't be an object. You can’t use index as a value for key. Assign unique keys to an incoming data set. To add new items to a data set, use a private property to track and generate keys. Use this code pattern.

iterator

To apply a special behavior to the first or last item in a list, use the iterator directive, iterator:iteratorName={array}. Add the iterator directive to a nested <template> tag that encloses the HTML elements you want to repeat.

Use iteratorName to access these properties:

This sample code uses the same array as the previous example. To apply special rendering to the first and last items in the list, the code uses the first and last properties with the if:true directive.

If the item is first in the list, the <div> tag renders with the styling defined in the CSS list-first class. If the item is last in the list, the <div> tag renders with the styling defined in the CSS list-last class.

Important

To access the value of a property in the array, use iteratorName.value.propertyName, not iteratorName.propertyName. For example, in helloIterator.html, look at {it.value.Name} and {it.value.Title}.

Render DOM Elements Conditionally

To render HTML conditionally, add the if:true|false={property} directive to a nested <template> tag that encloses the conditional content.

The directive binds property to the template and removes and inserts DOM elements based on whether property is a truthy or falsy value.

This simple example component has a propery called isTrueTemplate. The component has two nested templates. Only one renders depending on the value of isTrueTemplate.

<!-- helloConditionalRendering.html -->
<template>
    <div>
      <template if:true={isTrueTemplate}>
        This is the true template.
      </template>
      <template if:false={isTrueTemplate}>
        This is the false template.
      </template>
    </div>
</template>

To change which nested template renders, change the value of isTrueTemplate to true in the component's JavaScript class.

Notice that the JavaScript doesn’t manipulate the DOM, it simply changes the value of a property.