You're viewing docs for an older version of Lit. Click here for the latest version.
Template syntax reference
lit-html templates are written using JavaScript template literals tagged with the html tag. The contents of the literal are mostly plain, declarative, HTML:
html`<h1>Hello World</h1>`
Bindings or expressions are denoted with the standard JavaScript syntax for template literals:
lit-html templates must be well-formed HTML, and bindings can only occur in certain places. The templates are parsed by the browser's built-in HTML parser before any values are interpolated.
No warnings. Most cases of malformed templates are not detectable by lit-html, so you won't see any warnings—just templates that don't behave as you expect—so take extra care to structure templates properly.
Follow these rules for well-formed templates:
Templates must be well-formed HTML when all expressions are replaced by empty values.
Bindings can only occur in attribute-value and text-content positions.
<!-- attribute value -->
<divlabel="${label}"></div>
<!-- text content -->
<div>${textContent}</div>
Expressions cannot appear where tag or attribute names would appear.
<!-- ERROR -->
<${tagName}></${tagName}>
<!-- ERROR -->
<div ${attrName}=true></div>
Templates can have multiple top-level elements and text.
Templates should not contain unclosed elements—they will be closed by the HTML parser.
Event listeners can be functions or objects with a handleEvent method. Listeners are passed as both the listener and options arguments to addEventListener/removeEventListener, so that the listener can carry event listener options like capture, passive, and once.
Primitives values are converted to strings when interpolated into text content or attribute values. They are checked for equality to the previous value so that the DOM is not updated if the value hasn't changed.
JavaScript asynchronous iterators provide a generic interface for asynchronous sequential access to data. Much like an iterator, a consumer requests the next data item with a call to next(), but with asynchronous iterators next() returns a Promise, allowing the iterator to provide the item when it's ready.
lit-html offers two directives to consume asynchronous iterators:
asyncAppend renders the values of an async iterable, appending each new value after the previous.
asyncReplace renders the values of an async iterable, replacing the previous value with the new value.
Caches the rendered DOM nodes for templates when they're not in use. The conditionalTemplate argument is an expression that can return one of several templates. cache renders the current value of conditionalTemplate. When the template changes, the directive caches the current DOM nodes before switching to the new value.
When lit-html re-renders a template, it only updates the modified portions: it doesn't create or remove any more DOM than it needs to. But when you switch from one template to another, lit-html needs to remove the old DOM and render a new DOM tree.
The cache directive caches the generated DOM for a given binding and input template. In the example above, it would cache the DOM for both the summaryView and detailView templates. When you switch from one view to another, lit-html just needs to swap in the cached version of the new view, and update it with the latest data.
Location: attribute bindings (must be the only binding in the class attribute)
Sets a list of classes based on an object. Each key in the object is treated as a class name, and if the value associated with the key is truthy, that class is added to the element.
Checks binding value against the live DOM value, instead of the previously bound value, when determining whether to update the value.
This is useful for cases where the DOM value may change from outside of lit-html. For example, when binding to an <input> element's value property, a content editable element's text, or to a custom element that changes its own properties or attributes.
In these cases if the DOM value changes, but the value set through lit-html bindings hasn't, lit-html won't know to update the DOM value and will leave it alone. If this is not what you want—if you want to overwrite the DOM value with the bound value no matter what—use the live() directive.
Example:
html`<input.value=${live(x)}>`
live() performs a strict equality check against the live DOM value, and if the new value is equal to the live value, does nothing. This means that live() should not be used when the binding will cause a type conversion. If you use live() with an attribute binding, make sure that only strings are passed in, or the binding will update every render.
Repeats a series of values (usually TemplateResults) generated from an iterable, and updates those items efficiently when the iterable changes. When the keyFn is provided, key-to-DOM association is maintained between updates by moving DOM when required, and is generally the most efficient way to use repeat since it performs minimum unnecessary work for insertions and removals.
Example:
import {repeat} from'lit-html/directives/repeat';
constmyTemplate= () =>html`
<ul>
${repeat(items, (i) =>i.id, (i, index) =>html`
<li>${index}: ${i.name}</li>`)}
</ul>
`;
If no keyFn is provided, repeat will perform similar to a simple map of items to values, and DOM will be reused against potentially different items.
Location: attribute bindings (must be the only binding in the style attribute)
The styleMap directive sets styles on an element based on an object, where each key in the object is treated as a style property, and the value is treated as the value for that property. For example:
For CSS properties that contain dashes, you can either use the camel-case equivalent, or put the property name in quotes. For example, you can write the CSS property font-family as either fontFamily or 'font-family':
{ fontFamily: 'roboto' }
{ 'font-family': 'roboto' }
The styleMap must be the only binding in the style attribute, but it can be combined with static values:
Renders the content of a <template> element as HTML.
Note, the template contents should be developer controlled and not user controlled. User controlled templates rendered with this directive could lead to XSS vulnerabilities.
Note, this is unsafe to use with any user-provided input that hasn't been sanitized or escaped, as it may lead to cross-site-scripting vulnerabilities.
Note, this is unsafe to use with any user-provided input that hasn't been sanitized or escaped, as it may lead to cross-site-scripting vulnerabilities.
Renders placeholder content until the final content is available.
Takes a series of values, including Promises. Values are rendered in priority order, with the first argument having the highest priority and the last argument having the lowest priority. If a value is a Promise, a lower-priority value will be rendered until it resolves.
The priority of values can be used to create placeholder content for async data. For example, a Promise with pending content can be the first (highest-priority) argument, and a non-promise loading indicator template can be used as the second (lower-priority) argument. The loading indicator renders immediately, and the primary content will render when the Promise resolves.