Properties and Attributes

Declare properties in your component’s JavaScript class. Reference the properties in your component’s template to dynamically update content.

Tip

Property and attribute are almost interchangeable terms and can be confusing. Generally speaking, in HTML we talk about attributes, and in JavaScript we talk about properties.

JavaScript Property Names

Property names in JavaScript are in camel case while HTML attribute names are in kebab case (dash-separated) to match HTML standards. For example, a JavaScript property named itemName maps to an HTML attribute named item-name.

Don’t start a property name with these characters.

Don’t use these reserved words for property names.

Private Properties

A private property can be used only by the component that defines it.

This example declares a private itemId property. A private property doesn’t have a decorator.

// todoItem.js
import { LightningElement, api } from 'lwc';
export default class TodoItem extends LightningElement {
    @api itemTitle = ''; // public
    itemId = '';         // private
}

To make a private property reactive, decorate it with @track.

// todoItem.js
import { LightningElement, api, track } from 'lwc';
export default class TodoItem extends LightningElement {
    @api itemTitle = ''; // public
    itemId = '';         // private
    @track state = { x: 100, y: 100 };   // private and reactive

}

Boolean Properties

Boolean attributes on standard HTML Elements are set to true by adding the attribute to the element. The absence of the attribute defaults the attribute to false. Therefore, the default value of an attribute is always false. Lightning web components use the same principle for boolean properties.

Statically Setting a Property

If you want to toggle the value of a boolean property in markup, you must default the value to false.

// bool.js
import { LightningElement, api } from 'lwc';

export default class Bool extends LightningElement {
    // Always set the default value for a boolean to false
    @api show = false;
}

Here’s the HTML file.

<!-- bool.html -->
<template>
    <p>show value: {show}</p>
</template>

This parent component consumes example-bool. Because the show attribute isn’t added to <example-bool>, the component displays show value: false.

<!-- parent.html -->
<template>
    <example-bool></example-bool>
</template>

To set the show property to true, add a show attribute with an empty value to the markup. This version of example-parent displays show value: true.

<!-- parent.html -->
<template>
    <example-bool show></example-bool>
</template>

If you set the default value for the show property to be true instead in bool.js, there’s no way to statically toggle the value to false in markup.

Dynamically Setting a Property

To toggle the value if the default property value is true, you can pass down a dynamic computed value from the parent component.

<!-- parent.html -->
<template>
    <example-bool show={computedValue}></example-bool>
</template>

Use a JavaScript getter in parent.js to return the value of {computedValue}.

Access HTML Global Attributes in JavaScript

We don't recommend using HTML global attributes, which are attributes like class and title that are common to all HTML elements. If you do use a global HTML attribute, decorate it with @api.

Some HTML global attributes don’t follow the Lightning Web Components camel case and kebab case convention. If you create a getter or setter for one of these HTML global attributes, in JavaScript, use the case in this list.

HTML Global Attribute Property in JavaScript
accesskey accessKey
bgcolor bgColor
colspan colSpan
contenteditable contentEditable
crossorigin crossOrigin
datetime dateTime
for htmlFor
formaction formAction
ismap isMap
maxlength maxLength
minlength minLength
novalidate noValidate
readonly readOnly
rowspan rowSpan
tabindex tabIndex
usemap useMap

For example, to access the HTML maxlength attribute of textarea in JavaScript, use maxLength.

Also, to access the for HTML attribute from JavaScript, use htmlFor.

Reflect JavaScript Properties to HTML Attributes

You can control whether public JavaScript properties appear as attributes in the rendered HTML of a Lightning web component. Allowing properties to appear as attributes is especially important when creating accessible components, because screen readers and other assistive technologies use HTML attributes.

All HTML attributes are reactive by default. When an attribute’s value changes in the component HTML, the component re-renders.

When you take control of an attribute by exposing it as a public property, the attribute no longer appears in the HTML output by default. To pass the value through to the rendered HTML as an attribute (to reflect the property), define a getter and setter for the property and call the setAttribute() method.

You can also perform operations in the setter. Use a private property to hold the computed value. Decorate the private property with @track to make the property reactive. If the property’s value changes, the component re-renders.

This example exposes title as a public property. It converts the title to uppercase and uses the tracked property privateTitle to hold the computed value of the title. The setter calls setAttribute() to reflect the property’s value to the HTML attribute.

// myComponent.js
import { LightningElement, api, track } from 'lwc';

export default class MyComponent extends LightningElement {
    @track privateTitle;

    @api
    get title() {
        return this.privateTitle;
    }

    set title(value) {
        this.privateTitle = value.toUpperCase();
        this.setAttribute('title', this.privateTitle);
    }
}
/* parent.html */
<template>
    <example-my-component title="Hover Over the Component to See Me"></example-my-component>
</template>
/* Generated HTML */
<example-my-component title="HOVER OVER THE COMPONENT TO SEE ME">
    <div>Reflecting Attributes Example</div>
</example-my-component>

To make sure that you understand how JavaScript properties reflect to HTML attributes, look at the same code without the call to setAttribute(). The generated HTML doesn’t include the title attribute.

// myComponent.js
import { LightningElement, api, track } from 'lwc';

export default class MyComponent extends LightningElement {
    @track privateTitle;

    @api
    get title() {
        return this.privateTitle;
    }

    set title(value) {
        this.privateTitle = value.toUpperCase();
        // this.setAttribute('title', this.privateTitle);
    }
}
/* parent.html */
<template>
    <example-my-component title="Hover Over the Component to See Me"></example-my-component>
</template>
/* Generated HTML */
<example-my-component>
    <div>Reflecting Attributes Example</div>
</example-my-component>

Before you set a value, check if the value has already been set by the consumer.

// myComponent.js 
import { LightningElement } from 'lwc';

export default class MyComponent extends LightningElement {

    connectedCallback() {
        const tabindex = this.getAttribute('tabindex');

        // Set the tabindex to 0 if it hasn’t been set by the consumer.
        if (!tabindex) {
            this.setAttribute('tabindex','0');
        }
    }
}

Setting the tabindex using this.setAttribute() results in this markup.

<example-my-component tabindex="0"></example-my-component>

To set these attributes, use setAttribute().

To hide HTML attributes from the rendered HTML, call removeAttribute().