LWC Data Attribute Patterns
Overview
data-* attributes are a simple, high-signal way to pass row/action context from templates into handlers without creating large numbers of bound closures.
Use them intentionally with consistent naming conventions.
Consensus Best Practices
- Standardize naming:
data-record-id,data-index,data-action. - Read from
event.currentTarget.dataset, notevent.target.dataset. - Parse numeric values explicitly (
Number(...)). - Keep attributes minimal and non-sensitive.
- Avoid storing full JSON blobs in
data-*when IDs are enough.
Pattern 1: Record Id on Action Buttons
<template for:each={records} for:item="record">
<lightning-button
key={record.Id}
data-record-id={record.Id}
label="View"
onclick={handleViewClick}>
</lightning-button>
</template>
handleViewClick(event) {
const recordId = event.currentTarget.dataset.recordId;
this.navigateToRecord(recordId);
}
Pattern 2: Multi-Action Table Rows
<button data-index={index} data-action="edit" onclick={handleRowAction}>Edit</button>
<button data-index={index} data-action="delete" onclick={handleRowAction}>Delete</button>
handleRowAction(event) {
const index = Number(event.currentTarget.dataset.index);
const action = event.currentTarget.dataset.action;
const row = this.rows[index];
if (action === 'edit') this.openEditor(row);
else if (action === 'delete') this.deleteRow(row);
}
Pattern 3: Event Delegation in Complex Cells
When nested elements exist inside clickable containers, attach data-* to the element owning the click handler and always read currentTarget.
Common Failure Modes
- Using
event.targetand receiving empty/incorrect dataset values. - Inconsistent attribute names across components.
- Treating all dataset values as numbers without conversion.
- Exposing sensitive info in data attributes rendered to DOM.