Skip to main content
Lit provides several decorators for declaratively accessing DOM elements inside a component’s render root or slot.

@query

Converts a class property into a getter that runs querySelector on the element’s renderRoot.

Import

import {query} from 'lit/decorators.js';

Signature

query(selector: string, cache?: boolean): QueryDecorator
selector
string
required
A CSS selector string passed to renderRoot.querySelector().
cache
boolean
default:"false"
When true, the query result is cached after the first non-null lookup. Subsequent reads return the cached value without querying the DOM again. Only use this when you know the queried element will not change after initial render.

Return type

Element | null

Example

import {LitElement, html} from 'lit';
import {query} from 'lit/decorators.js';

class MyElement extends LitElement {
  @query('#input')
  inputEl!: HTMLInputElement;

  render() {
    return html`<input id="input" type="text" />`;
  }

  focus() {
    this.inputEl?.focus();
  }
}

@queryAll

Converts a class property into a getter that runs querySelectorAll on the element’s renderRoot.

Import

import {queryAll} from 'lit/decorators.js';

Signature

queryAll(selector: string): QueryAllDecorator
selector
string
required
A CSS selector string passed to renderRoot.querySelectorAll().

Return type

NodeListOf<Element>

Example

import {LitElement, html} from 'lit';
import {queryAll} from 'lit/decorators.js';

class MyList extends LitElement {
  @queryAll('li')
  listItems!: NodeListOf<HTMLLIElement>;

  render() {
    return html`
      <ul>
        <li>First</li>
        <li>Second</li>
        <li>Third</li>
      </ul>
    `;
  }

  logItems() {
    this.listItems.forEach((li) => console.log(li.textContent));
  }
}

@queryAsync

Converts a class property into a getter that returns a Promise resolving to the result of querySelector after the element’s next update completes. Useful when the queried element’s presence depends on reactive state that may not have been rendered yet.

Import

import {queryAsync} from 'lit/decorators.js';

Signature

queryAsync(selector: string): QueryAsyncDecorator
selector
string
required
A CSS selector string passed to renderRoot.querySelector(), evaluated after updateComplete resolves.

Return type

Promise<Element | null>

Example

import {LitElement, html} from 'lit';
import {state, queryAsync} from 'lit/decorators.js';

class MyElement extends LitElement {
  @state() private _showInput = false;

  @queryAsync('#input')
  inputEl!: Promise<HTMLInputElement | null>;

  render() {
    return html`
      <button @click=${() => (this._showInput = true)}>Show input</button>
      ${this._showInput ? html`<input id="input" />` : ''}
    `;
  }

  async focusInput() {
    const input = await this.inputEl;
    input?.focus();
  }
}

@queryAssignedElements

Converts a class property into a getter that returns the elements assigned to a slot using HTMLSlotElement.assignedElements().

Import

import {queryAssignedElements} from 'lit/decorators.js';

Signature

queryAssignedElements(options?: QueryAssignedElementsOptions): QueryAssignedElementsDecorator

Options

slot
string
Name of the slot to query. Omit to query the default (unnamed) slot.
flatten
boolean
default:"false"
When true, recursively returns elements from nested slots. Passed directly to HTMLSlotElement.assignedElements({flatten}).
selector
string
A CSS selector to filter the assigned elements. Only elements matching this selector are included in the result.

Return type

Array<Element>

Example

import {LitElement, html} from 'lit';
import {queryAssignedElements} from 'lit/decorators.js';

class MyTabs extends LitElement {
  @queryAssignedElements({slot: 'tab'})
  tabs!: Array<HTMLElement>;

  @queryAssignedElements()
  panels!: Array<HTMLElement>;

  render() {
    return html`
      <slot name="tab"></slot>
      <slot></slot>
    `;
  }

  updated() {
    console.log('Tab count:', this.tabs.length);
  }
}

@queryAssignedNodes

Converts a class property into a getter that returns the nodes assigned to a slot using HTMLSlotElement.assignedNodes(). Includes text nodes; use @queryAssignedElements if you only need element nodes.

Import

import {queryAssignedNodes} from 'lit/decorators.js';

Signature

queryAssignedNodes(options?: QueryAssignedNodesOptions): QueryAssignedNodesDecorator

Options

slot
string
Name of the slot to query. Omit to query the default (unnamed) slot.
flatten
boolean
default:"false"
When true, recursively returns nodes from nested slots. Passed directly to HTMLSlotElement.assignedNodes({flatten}).

Return type

Array<Node>

Example

import {LitElement, html} from 'lit';
import {queryAssignedNodes} from 'lit/decorators.js';

class MyElement extends LitElement {
  @queryAssignedNodes({slot: 'list', flatten: true})
  listNodes!: Array<Node>;

  render() {
    return html`<slot name="list"></slot>`;
  }
}

Build docs developers (and LLMs) love