Built-in directives
Directives are functions that can extend Lit by customizing the way an expression renders. Lit includes a number of built-in directives to help with a variety of rendering needs:
Directive | Summary |
---|---|
Styling | |
Assigns a list of classes to an element based on an object. | |
Sets a list of style properties to an element based on an object. | |
Loops and Conditionals | |
Renders one of two templates based on a condition. | |
Renders one of many templates based on a key value. | |
Transforms an iterable with a function. | |
Renders values from an iterable into the DOM, with optional keying to enable data diffing and DOM stability. | |
Interleave values from an iterable with a joiner value. | |
Creates an iterable of numbers in a sequence, useful for iterating a specific number of times. | |
Sets an attribute if the value is defined and removes the attribute if undefined. | |
Caching and change detection | |
Caches rendered DOM when changing templates rather than discarding the DOM. | |
Associates a renderable value with a unique key, forcing the DOM to re-render if the key changes. | |
Only re-evaluates the template when one of its dependencies changes. | |
Sets an attribute or property if it differs from the live DOM value rather than the last-rendered value. | |
Referencing rendered DOM | |
Gets a reference to an element rendered in the template. | |
Rendering special values | |
Renders the content of a | |
Renders a string as HTML rather than text. | |
Renders a string as SVG rather than text. | |
Asynchronous rendering | |
Renders placeholder content until one or more promises resolve. | |
Appends values from an | |
Renders the latest value from an |
Only bundle what you use. These are called "built-in" directives because they're part of the Lit package. But each directive is a separate module, so your app only bundles the directives you import.
You can also build your own directives. For more information, see Custom directives.
Styling
Permalink to “Styling”classMap
Permalink to “classMap”Sets a list of classes to an element based on an object.
Import |
|
Signature |
|
Usable location |
|
The classMap
directive uses the element.classList
API to efficiently add and remove classes to an element based on an object passed by the user. 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. On subsequent renders, any previously set classes that are falsy or no longer in the object are removed.
The classMap
must be the only expression in the class
attribute, but it can be combined with static values:
Explore classMap
more in the playground.
styleMap
Permalink to “styleMap”Sets a list of style properties to an element based on an object.
Import |
|
Signature |
|
Usable location |
|
The styleMap
directive uses the element.style
API to efficiently add and remove inline styles to an element based on an object passed by the user. Each key in the object is treated as a style property name, the value is treated as the value for that property. On subsequent renders, any previously set style properties that are undefined or null
are removed (set to null
).
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'
:
Refer to CSS custom properties such as --custom-color
, by placing the whole property name in quotes:
The styleMap
must be the only expression in the style
attribute, but it can be combined with static values:
Explore styleMap
more in the playground.
Loops and conditionals
Permalink to “Loops and conditionals”Renders one of two templates based on a condition.
Import |
|
Signature |
|
Usable location | Any |
When condition
is true, returns the result of calling trueCase()
, else returns the result of calling falseCase()
if falseCase
is defined.
This is a convenience wrapper around a ternary expression that makes it a little nicer to write an inline conditional without an else.
choose
Permalink to “choose”Chooses and evaluates a template function from a list of cases based on matching the given value
to a case.
Import |
|
Signature |
|
Usable location | Any |
Cases are structured as [caseValue, func]
. value
is matched to caseValue
by strict equality. The first match is selected. Case values can be of any type including primitives, objects, and symbols.
This is similar to a switch statement, but as an expression and without fallthrough.
Returns an iterable containing the result of calling f(value)
on each value in items
.
Import |
|
Signature |
|
Usable location | Any |
map()
is a simple wrapper around a for/of loop that makes working with iterables in expressions a bit easier. map()
always updates any DOM created in place - it does not do any diffing or DOM movement. If you need that see repeat. map()
is smaller and faster than repeat()
, so if you don't need diffing and DOM stability, prefer map()
.
repeat
Permalink to “repeat”Renders values from an iterable into the DOM, with optional keying to enable data diffing and DOM stability.
Import |
|
Signature |
|
Usable location | Child expression |
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 generated DOM when required, and is generally the most efficient way to use repeat
since it performs minimum unnecessary work for insertions and removals.
If you're not using a key function, you should consider using map()
.
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.
See When to use map or repeat for a discussion of when to use repeat
and when to use standard JavaScript flow control.
Explore repeat
more in the playground.
Returns an iterable containing the values in items
interleaved with the joiner
value.
Import |
|
Signature |
|
Usable location | Any |
range
Permalink to “range”Returns an iterable of integers from start
to end
(exclusive) incrementing by step
.
Import |
|
Signature |
|
Usable location | Any |
ifDefined
Permalink to “ifDefined”Sets an attribute if the value is defined and removes the attribute if undefined.
Import |
|
Signature |
|
Usable location | Attribute expression |
For AttributeParts, sets the attribute if the value is defined and removes the attribute if the value is undefined (undefined
or null
). For other part types, this directive is a no-op.
When more than one expression exists in a single attribute value, the attribute will be removed if any expression uses ifDefined
and evaluates to undefined
/null
. This is especially useful for setting URL attributes, when the attribute should not be set if required parts of the URL are not defined, to prevent 404's.
Explore ifDefined
more in the playground.
Caching and change detection
Permalink to “Caching and change detection”cache
Permalink to “cache”Caches rendered DOM when changing templates rather than discarding the DOM. You can use this directive to optimize rendering performance when frequently switching between large templates.
Import |
|
Signature |
|
Usable location | Child expression |
When the value passed to cache
changes between one or more TemplateResult
s, the rendered DOM nodes for a given template are cached when they're not in use. When the template changes, the directive caches the current DOM nodes before switching to the new value, and restores them from the cache when switching back to a previously-rendered value, rather than creating the DOM nodes anew.
When Lit re-renders a template, it only updates the modified portions: it doesn't create or remove any more DOM than needed. But when you switch from one template to another, Lit removes the old DOM and renders a new DOM tree.
The cache
directive caches the generated DOM for a given expression and input template. In the example above, it caches the DOM for both the summaryView
and detailView
templates. When you switch from one view to another, Lit swaps in the cached version of the new view and updates it with the latest data. This can improve rendering performance when these views are frequently switched.
Explore cache
more in the playground.
keyed
Permalink to “keyed”Associates a renderable value with a unique key. When the key changes, the previous DOM is removed and disposed before rendering the next value, even if the value—such as a template—is the same.
Import |
|
Signature |
|
Usable location | Any expression |
keyed
is useful when you're rendering stateful elements and you need to ensure that all state of the element is cleared when some critical data changes. It essentially opts-out of Lit's default DOM reuse strategy.
keyed
is also useful in some animation scenarios if you need to force a new element for "enter" or "exit" animations.
guard
Permalink to “guard”Only re-evaluates the template when one of its dependencies changes, to optimize rendering performance by preventing unnecessary work.
Import |
|
Signature |
|
Usable location | Any expression |
Renders the value returned by valueFn
, and only re-evaluates valueFn
when one of the dependencies changes identity.
Where:
dependencies
is an array of values to monitor for changes.valueFn
is a function that returns a renderable value.
guard
is useful with immutable data patterns, by preventing expensive work until data updates.
In this case, the expensive calculateSHA
function is only run when the value
property changes.
Explore guard
more in the playground.
Sets an attribute or property if it differs from the live DOM value rather than the last-rendered value.
Import |
|
Signature |
|
Usable location | Attribute or property expression |
When determining whether to update the value, checks the expression value against the live DOM value, instead of Lit's default behavior of checking against the last set value.
This is useful for cases where the DOM value may change from outside of Lit. For example, when using an expression to set 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 expression hasn't, Lit 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.
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 expression will cause a type conversion. If you use live()
with an attribute expression, make sure that only strings are passed in, or the expression will update every render.
Explore live
more in the playground.
Rendering special values
Permalink to “Rendering special values”templateContent
Permalink to “templateContent”Renders the content of a <template>
element.
Import |
|
Signature |
|
Usable location | Child expression |
Lit templates are encoded in Javascript, so that they can embed Javascript expressions that make them dynamic. If you have a static HTML <template>
that you need to include in your Lit template, you can use the templateContent
directive to clone the template content and include it in your Lit template. As long as the template element reference does not change between renders, subsequent renders will no-op.
Note, the template content should be developer-controlled and must not be created using an untrusted string. Examples of untrusted content include query string parameters and values from user inputs. Untrusted templates rendered with this directive could lead to cross-site scripting (XSS) vulnerabilities.
Explore templateContent
more in the playground.
unsafeHTML
Permalink to “unsafeHTML”Renders a string as HTML rather than text.
Import |
|
Signature |
|
Usable location | Child expression |
A key feature of Lit's templating syntax is that only strings originating in template literals are parsed as HTML. Because template literals can only be authored in trusted script files, this acts as a natural safeguard against XSS attacks injecting untrusted HTML. However, there may be cases when HTML not originating in script files needs to be rendered in a Lit template, for example trusted HTML content fetched from a database. The unsafeHTML
directive will parse such a string as HTML and render it in a Lit template.
Note, the string passed to unsafeHTML
must be developer-controlled and not include untrusted content. Examples of untrusted content include query string parameters and values from user inputs.
Untrusted content rendered with this directive could lead to cross-site scripting (XSS), CSS injection, data exfiltration, etc. vulnerabilities. unsafeHTML
uses innerHTML
to parse the HTML string, so the security implications are the same as innerHTML
, as documented on MDN.
Explore unsafeHTML
more in the playground.
unsafeSVG
Permalink to “unsafeSVG”Renders a string as SVG rather than text.
Import |
|
Signature |
|
Usable location | Child expression |
Similar to with unsafeHTML
, there may be cases when SVG content not originating in script files needs to be rendered in a Lit template, for example trusted SVG content fetched from a database. The unsafeSVG
directive will parse such a string as SVG and render it in a Lit template.
Note, the string passed to unsafeSVG
must be developer-controlled and not include untrusted content. Examples of untrusted content include query string parameters and values from user inputs. Untrusted content rendered with this directive could lead to cross-site scripting (XSS) vulnerabilities.
Explore unsafeSVG
more in the playground.
Referencing rendered DOM
Permalink to “Referencing rendered DOM”Retrieves a reference to an element rendered into the DOM.
Import |
|
Signature |
|
Usable location | Element expression |
Although most DOM manipulation in Lit can be achieved declaratively using templates, advanced situations may required getting a reference to an element rendered in the template and manipulating it imperatively. Common examples of when this may be useful include focusing a form control or calling an imperative DOM manipulation library on a container element.
When placed on an element in the template, the ref
directive will retrieve a reference to that element once rendered. The element reference may be retrieved in one of two ways: either by passing a Ref
object or by passing a callback.
A Ref
object acts as a container for a reference to the element, and can be created using the createRef
helper method found in the ref
module. After rendering, the Ref
's value
property will be set to the element, where it can be accessed in post-render lifecycle like updated
.
A ref callback can also be passed to the ref
directive. The callback will be called each time the referenced element changes. If a ref callback is rendered to a different element position or is removed in a subsequent render, it will first be called with undefined
, followed by another call with the new element it was rendered to (if any). Note that in a LitElement
, the callback will be called bound to the host element automatically.
Explore ref
more in the playground.
Asynchronous rendering
Permalink to “Asynchronous rendering”until
Permalink to “until”Renders placeholder content until one or more promises resolve.
Import |
|
Signature |
|
Usable location | Any expression |
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.
Explore until
more in the playground.
asyncAppend
Permalink to “asyncAppend”Appends values from an AsyncIterable
into the DOM as they are yielded.
Import |
|
Signature |
|
Usable location | Child expression |
asyncAppend
renders the values of an async iterable, appending each new value after the previous. Note that async generators also implement the async iterable protocol, and thus can be consumed by asyncAppend
.
Explore asyncAppend
more in the playground.
asyncReplace
Permalink to “asyncReplace”Renders the latest value from an AsyncIterable
into the DOM as it is yielded.
Import |
|
Signature |
|
Usable location | Any expression |
Similar to asyncAppend
, asyncReplace
renders the values of an async iterable, replacing the previous value with each new value.
Explore asyncReplace
more in the playground.