Lifecycle Callbacks
Custom elements are not just inert tags — they have a lifecycle. The browser calls specific methods on your class at well-defined moments: when the element is created, when it is inserted into the document, when its attributes change, and when it is removed. Handling these moments correctly is the foundation of a well-behaved custom element.
This module covers four lifecycle callbacks:
constructor— element is created (class instantiated)connectedCallback— element is inserted into a documentattributeChangedCallback— an observed attribute is added, changed, or removeddisconnectedCallback— element is removed from a document
It also covers upgrading — what happens when the browser encounters a custom element tag before the class is registered.
Lifecycle sequence
Section titled “Lifecycle sequence”flowchart LR C["constructor (element created)"] CC["connectedCallback (inserted into DOM)"] AC["attributeChangedCallback (attribute changed) — fires each time —"] DC["disconnectedCallback (removed from DOM)"] C --> CC CC --> AC AC --> AC CC --> DC
| Callback | When it fires |
|---|---|
constructor | Element is instantiated — via new or HTML parsing |
connectedCallback | Element is inserted into any document (or shadow root) |
attributeChangedCallback | An observed attribute is set, changed, or removed |
disconnectedCallback | Element is removed from the document |
The attributeChangedCallback can fire multiple times — once per attribute change — and it fires both before and after the element is connected depending on when attributes are set.
constructor
Section titled “constructor”constructor is called when a new instance of the element is created, whether through document.createElement or the browser’s HTML parser. The one hard rule: call super() as the very first statement, and never touch the DOM, attributes, or children at this point.
connectedCallback
Section titled “connectedCallback”connectedCallback is called every time the element is inserted into a connected document. This is the right place to render and to set up event listeners.
attributeChangedCallback
Section titled “attributeChangedCallback”attributeChangedCallback is called when an attribute listed in observedAttributes is added, changed, or removed. You must declare the list of attributes to observe with a static getter named observedAttributes.
disconnectedCallback
Section titled “disconnectedCallback”disconnectedCallback is called when the element is removed from the DOM. Use it for cleanup — removing event listeners or cancelling timers.
Upgrading existing elements
Section titled “Upgrading existing elements”If the browser encounters <my-widget> in the HTML before the class is registered, it creates a plain HTMLElement first. When customElements.define('my-widget', MyWidget) is later called, the browser upgrades those elements by running their constructor and, if they are already in the DOM, their connectedCallback. You can await an upgrade with customElements.whenDefined('my-widget').
Live demo
Section titled “Live demo”The element below logs each lifecycle event it observes. Click Remove element to trigger disconnectedCallback, then re-add it to see connectedCallback fire again.