# Component API

The whole API provided by stencil can be condensed in a set of decorators, lifecycles hooks and rendering methods.

## Decorators[​](#decorators "Direct link to Decorators")

Decorators are a pure compiler-time construction used by stencil to collect all the metadata about a component, the properties, attributes and methods it might expose, the events it might emit or even the associated stylesheets. Once all the metadata has been collected, all the decorators are removed from the output, so they don't incur any runtime overhead.

* [@Component()](/docs/component.md) declares a new web component
* [@Prop()](/docs/properties.md#the-prop-decorator-prop) declares an exposed property/attribute
* [@State()](/docs/state.md#the-state-decorator-state) declares an internal state of the component
* [@Watch()](/docs/reactive-data.md#the-watch-decorator-watch) declares a hook that runs when a property or state changes
* [@Element()](/docs/host-element.md#element-decorator) declares a reference to the host element
* [@Method()](/docs/methods.md) declares an exposed public method
* [@Event()](/docs/events.md#event-decorator) declares a DOM event the component might emit
* [@Listen()](/docs/events.md#listen-decorator) listens for DOM events
* [@AttrDeserialize()](/docs/serialization.md#the-attrdeserialize-decorator-attrdeserialize) declares a hook to translate a component's attribute string to its JS property
* [@PropSerialize()](/docs/serialization.md#the-propserialize-decorator-propserialize) declares a hook that translates a component's JS property to its attribute string
* [@AttachInternals()](/docs/attach-internals.md) attaches ElementInternals to a component

## Lifecycle hooks[​](#lifecycle-hooks "Direct link to Lifecycle hooks")

* [connectedCallback()](/docs/component-lifecycle.md#connectedcallback)
* [disconnectedCallback()](/docs/component-lifecycle.md#disconnectedcallback)
* [componentWillLoad()](/docs/component-lifecycle.md#componentwillload)
* [componentDidLoad()](/docs/component-lifecycle.md#componentdidload)
* [componentShouldUpdate(newValue, oldValue, propName): boolean](/docs/component-lifecycle.md#componentshouldupdate)
* [componentWillRender()](/docs/component-lifecycle.md#componentwillrender)
* [componentDidRender()](/docs/component-lifecycle.md#componentdidrender)
* [componentWillUpdate()](/docs/component-lifecycle.md#componentwillupdate)
* [componentDidUpdate()](/docs/component-lifecycle.md#componentdidupdate)
* **[render()](/docs/templating-jsx.md)**

## componentOnReady()[​](#componentonready "Direct link to componentOnReady()")

This isn't a true "lifecycle" method that would be declared on the component class definition, but instead is a utility method that can be used by an implementation consuming your Stencil component to detect when a component has finished its first render cycle.

This method returns a promise which resolves after `componentDidRender()` on the *first* render cycle.

note

`componentOnReady()` only resolves once per component lifetime. If you need to hook into subsequent render cycle, use `componentDidRender()` or `componentDidUpdate()`.

Executing code after `componentOnReady()` resolves could look something like this:

```
// Get a reference to the element
const el = document.querySelector('my-component');

el.componentOnReady().then(() => {
  // Place any code in here you want to execute when the component is ready
  console.log('my-component is ready');
});
```

The availability of `componentOnReady()` depends on the component's compiled output type. This method is only available for lazy-loaded distribution types ([`dist`](/docs/distribution.md) and [`www`](/docs/www.md)) and, as such, is not available for [`dist-custom-elements`](/docs/custom-elements.md) output. If you want to simulate the behavior of `componentOnReady()` for non-lazy builds, you can implement a helper method to wrap the functionality similar to what the Ionic Framework does [here](https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/helpers.ts#L60-L79).

## The `appload` event[​](#the-appload-event "Direct link to the-appload-event")

In addition to component-specific lifecycle hooks, a special event called `appload` will be emitted when the app and all of its child components have finished loading. You can listen for it on the `window` object.

If you have multiple apps on the same page, you can determine which app emitted the event by checking `event.detail.namespace`. This will be the value of the [namespace config option](/docs/config.md#namespace) you've set in your Stencil config.

```
window.addEventListener('appload', (event) => {
  console.log(event.detail.namespace);
});
```

## Other[​](#other "Direct link to Other")

The following primitives can be imported from the `@stencil/core` package and used within the lifecycle of a component:

### [**Host**](/docs/host-element.md):[​](#host "Direct link to host")

`<Host>`, is a functional component that can be used at the root of the render function to set attributes and event listeners to the host element itself. Refer to the [Host Element](/docs/host-element.md) page for usage info.

### **Fragment**:[​](#fragment "Direct link to fragment")

`<Fragment>`, often used via `<>...</>` syntax, lets you group elements without a wrapper node.

To use this feature, ensure that the following TypeScript compiler options are set:

* [`jsxFragmentFactory` is set](https://www.typescriptlang.org/tsconfig#jsxFragmentFactory) to "Fragment"
* [`jsxFactory` is set](https://www.typescriptlang.org/tsconfig#jsxFactory) to "h"

**Type:** `FunctionalComponent`<br />**Example:**

```
import { Component, Fragment, h } from '@stencil/core'
@Component({
  tag: 'cmp-fragment',
})
export class CmpFragment {
  render() {
    return (
      <>
        <div>...</div>
        <div>...</div>
        <div>...</div>
      </>
    );
  }
}
```

### [**h()**](/docs/templating-jsx.md):[​](#h "Direct link to h")

Turns JSX syntax into Virtual DOM elements. Read more on the [Templating and JSX](/docs/templating-jsx.md#the-h-and-fragment-functions) page.

### **render()**:[​](#render "Direct link to render")

A utility method to render a virtual DOM created by `h()` into a container.

**Type:** `(vnode: VNode, container: Element) => void` **Example:**

```
import { render } from '@stencil/core'
const vdom = (
  <div className="m-2">Hello World!</div>
)
render(vdom, document.body)
```

### [**readTask()**](https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing):[​](#readtask "Direct link to readtask")

Schedules a DOM-read task. The provided callback will be executed in the best moment to perform DOM reads without causing layout thrashing.

**Type:** `(task: Function) => void`

### [**writeTask()**](https://developers.google.com/web/fundamentals/performance/rendering/avoid-large-complex-layouts-and-layout-thrashing):[​](#writetask "Direct link to writetask")

Schedules a DOM-write task. The provided callback will be executed in the best moment to perform DOM mutations without causing layout thrashing.

**Type:** `(task: Function) => void`

### **forceUpdate()**:[​](#forceupdate "Direct link to forceupdate")

Schedules a new render of the given instance or element even if no state changed. Notice `forceUpdate()` is not synchronous and might perform the DOM render in the next frame.

**Type:** `(ref: any) => void`<br />**Example:**

```
import { forceUpdate } from '@stencil/core'

// inside a class component function
forceUpdate(this);
```

### **getAssetPath()**:[​](#getassetpath "Direct link to getassetpath")

Gets the path to local assets. Refer to the [Assets](/docs/assets.md#getassetpath) page for usage info.

**Type:** `(path: string) => string`<br />**Example:**

```
import { Component, Prop, getAssetPath, h } from '@stencil/core'
@Component({
  tag: 'cmp-asset',
})
export class CmpAsset {
  @Prop() icon: string;

  render() {
    return (
      <img src={getAssetPath(`assets/icons/${this.icon}.png`)} />
    );
  }
}
```

### **setAssetPath()**:[​](#setassetpath "Direct link to setassetpath")

Sets the path for Stencil to resolve local assets. Refer to the [Assets](/docs/assets.md#setassetpath) page for usage info.

**Type:** `(path: string) => string`<br />**Example:**

```
import { setAssetPath } from '@stencil/core';
setAssetPath(`{window.location.origin}/`);
```

### **setMode()**:[​](#setmode "Direct link to setmode")

Sets the style mode of a component. Refer to the [Styling](/docs/styling.md#style-modes) page for usage info.

**Type:** `((elm: HTMLElement) => string | undefined | null) => void`<br />**Example:**

```
import { setMode } from '@stencil/core'

// set mode based on a property
setMode((el) => el.getAttribute('mode'));
```

### **getMode()**:[​](#getmode "Direct link to getmode")

Get the current style mode of your application. Refer to the [Styling](/docs/styling.md#style-modes) page for usage info.

**Type:** `(ref: any) => string | undefined`<br />**Example:**

```
import { getMode } from '@stencil/core'

getMode(this);
```

### **getElement()**:[​](#getelement "Direct link to getelement")

Retrieve a Stencil element for a given reference.

**Type:** `(ref: any) => HTMLStencilElement`<br />**Example:**

```
import { getElement } from '@stencil/core'

const stencilComponent = getElement(document.querySelector('my-cmp'))
if (stencilComponent) {
  stencilComponent.componentOnReady().then(() => { ... })
}
```

### **resolveVar()**:[​](#resolvevar "Direct link to resolvevar")

Because Stencil's decorators rely heavily on static analysis, you cannot use dynamic variables within them. `resolveVar` provides a deterministic way to find the string value of a given variable at compile time:

**Type:** `(variable: T) => string`<br />**Example:**

```
import { Listen, Event, resolveVar } from '@stencil/core`

const COMPONENT_A_EVENT: string = 'componentAEvent';
const EVENTS = {
  COMPONENT_B_EVENT: 'componentBEvent',
};

// inside an @Component class

@Component({
  tag: 'dynamic-event-names',
})
export class DynamicEventNames {
  @Event({ eventName: resolveVar(COMPONENT_A_EVENT) }) myEvent;
  
  @Listen(resolveVar(EVENTS.COMPONENT_B_EVENT))
  listenHandler(){
    //
  }
}
```

### **Mixin()**:[​](#mixin "Direct link to mixin")

Compose multiple classes into a single constructor using factory functions.

**Type:**

```
<TMixins extends readonly MixinFactory[]>(
  ...mixinFactories: TMixins
): abstract new (...args: any[]) => UnionToIntersection<InstanceType<ReturnType<TMixins[number]>>>;
```

**Example:**

```
import { Mixin, MixedInCtor, Component, h, Prop, State } from '@stencil/core'

const aFactory = <B extends MixedInCtor>(Base: B) => {
  class A extends Base { propA = 'A' };
  return A;
}
const bFactory = <B extends MixedInCtor>(Base: B) => {
  class B extends Base { @Prop() propB = 'B' };
  return B;
}
const cFactory = <B extends MixedInCtor>(Base: B) => {
  class C extends Base { @State() propC = 'C' };
  return C;
}

@Component({
  tag: 'its-mixing-time',
})
export class X extends Mixin(aFactory, bFactory, cFactory) {
  render() {
    return <div>{this.propA} {this.propB} {this.propC}</div>
  }
}
```

caution

If your Stencil component library uses `Mixin()` (or `extends`) and *might* be used by other Stencil component libraries, ensure that all mixed-in factories are imported directly and **not** via [barrel files](https://basarat.gitbook.io/typescript/main-1/barrel). The static-analysis that Stencil uses to find mixed-in classes does not work within 3rd party (node\_module) barrel files.

For detailed guidance on using `Mixin()` and `extends` for component architecture, including when to use inheritance vs composition patterns, see the [Extends & Mixins](/docs/extends.md) guide.

### [**setTagTransformer()** and **transformTag()**](/docs/tag-transformation.md):[​](#settagtransformer-and-transformtag "Direct link to settagtransformer-and-transformtag")

Manage tag name transformation at runtime. Refer to the [Tag Transformation](/docs/tag-transformation.md) page for usage info.
