Sitemap

Mastering template.querySelectorAll in LWC: A Comprehensive Guide

3 min readJun 5, 2025

--

When working with Lightning Web Components (LWC), selecting DOM elements efficiently is crucial for dynamic interactions. While searching for the best ways to use template.querySelectorAll, I realized there wasn’t a single consolidated resource covering all possible selector patterns. So, I decided to compile everything—from basic tag selections to advanced attribute-based queries—into one definitive guide.

Whether you’re manipulating multiple elements, applying dynamic styles, or handling form inputs, knowing how to leverage querySelectorAll effectively can save time and reduce code complexity.

During a recent project, I needed to select multiple elements with different criteria — some by class, some by data attributes, and others by their position in the DOM. After digging through documentation and scattered examples, I thought: Wouldn’t it be great to have all these methods in one place?

Probable Use Case

Imagine a dynamic form where you need to:

  • Validate all required inputs (querySelectorAll('lightning-input[required]')).
  • Highlight error fields with a specific CSS class (querySelectorAll('.error-field')).
  • Disable all buttons after submission (querySelectorAll('button')).

Instead of writing repetitive queries, mastering querySelectorAll helps you handle such scenarios cleanly.

Sample HTML

<template>
<div class="container">
<h1>querySelectorAll Examples</h1>

<!-- Tag examples -->
<p>This is a paragraph (tag selector)</p>
<p class="special">This is a special paragraph</p>

<!-- Class examples -->
<div class="my-class">Element with class "my-class"</div>
<div class="my-class another-class">Element with multiple classes</div>

<!-- Attribute examples -->
<div data-id="123" data-status="active">Element with data attributes</div>
<div data-status="inactive">Inactive element</div>

<!-- Input examples -->
<lightning-input
label="Name"
required
class="input-field"
data-type="text">
</lightning-input>

<lightning-input
label="Email"
type="email"
class="input-field"
data-type="email">
</lightning-input>

<!-- List examples -->
<ul class="item-list">
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item special-item">Item 3 (special)</li>
</ul>

<!-- Button with data attribute -->
<button class="button-primary" data-action="submit">Submit</button>
</div>
</template>

Sample JS

import { LightningElement } from 'lwc';

export default class ExampleComponent extends LightningElement {
renderedCallback() {
if (!this.hasRendered) {
// 1. Selecting by Tag Name
const paragraphs = this.template.querySelectorAll('p');
console.log('Paragraph tags:', paragraphs.length); // 2

// 2. Selecting by Class Name
const myClassElements = this.template.querySelectorAll('.my-class');
console.log('Elements with my-class:', myClassElements.length); // 2

// 3. Selecting by Attribute
const dataAttrElements = this.template.querySelectorAll('[data-id]');
console.log('Elements with data-id:', dataAttrElements.length); // 1

// 4. Selecting by Specific Attribute Value
const activeElements = this.template.querySelectorAll('[data-status="active"]');
console.log('Active elements:', activeElements.length); // 1

// 5. Selecting by Data Attributes
const inputFields = this.template.querySelectorAll('lightning-input[data-type]');
console.log('Input fields with data-type:', inputFields.length); // 2

// 6. Combining Selectors
const specialParagraph = this.template.querySelectorAll('p.special');
console.log('Special paragraphs:', specialParagraph.length); // 1

// 7. Selecting Children of a Specific Element
const list = this.template.querySelector('ul.item-list');
const listItems = list.querySelectorAll('li.item');
console.log('List items:', listItems.length); // 3

// 8. Selecting Pseudo-classes (works but less commonly used in JS)
// Note: Pseudo-classes like :hover won't work in querySelectorAll for state-based selectors
const firstListItem = this.template.querySelectorAll('li.item:first-child');
console.log('First list item:', firstListItem.length); // 1

// 9. Selecting Multiple Types
const headingsAndParagraphs = this.template.querySelectorAll('h1, p');
console.log('Headings and paragraphs:', headingsAndParagraphs.length); // 3

// 10. Selecting by Attribute Prefix/Suffix
const primaryButtons = this.template.querySelectorAll('[class$="-primary"]');
console.log('Primary buttons:', primaryButtons.length); // 1

this.hasRendered = true;
}
}
}

Happy coding — and may your selectors always return exactly what you expect (or at least fail loudly so you can debug them)! 😆

--

--

No responses yet