--- title: Create custom native web components slug: latest-custom-web-components canonical_url: https://docs.coveo.com/en/atomic/latest/usage/custom-web-components/ collection: atomic source_format: adoc --- # Create custom native web components [Coveo Atomic](https://docs.coveo.com/en/lcdf0264/) components fulfill most use cases, follow best UX practices, and are visually [customizable](https://docs.coveo.com/en/atomic/latest/usage/themes-and-visual-customization/). However, you may sometimes need more features, further visual customization, or a different behavior altogether. In such cases, build your own custom components. This article explains how to do so by providing two commented examples. ## Custom component example The following code sample implements a custom dropdown [facet](https://docs.coveo.com/en/198/) component. ```html ``` <1> The [`initializeBindings`](https://github.com/coveo/ui-kit/tree/main/packages/atomic#initializebindings--bindstatetocontroller-decorators) method retrieves the [Atomic](https://docs.coveo.com/en/lcdf0264/) bindings from the parent `atomic-search-interface`. This lets you access the [Headless](https://docs.coveo.com/en/lcdf0493/) engine to create controllers, dispatch actions, access the controller state, and so on, as you'll do in the next section. <2> Import the [`buildFacet`](https://docs.coveo.com/en/headless/latest/reference/functions/Search.buildFacet.html) method to create your facet controller. <3> When disconnecting components from the page, we also recommend that you remove state change listeners by calling the unsubscribe methods. <4> Initialize the bindings and [Headless](https://docs.coveo.com/en/lcdf0493/) controllers using the [`connectedCallback`](https://stenciljs.com/docs/component-lifecycle#connectedcallback) lifecycle method with `async`/`await`. <5> Wait for the [Atomic](https://docs.coveo.com/en/lcdf0264/) bindings to be initialized on your component. <6> Initialize the controller using the [Atomic](https://docs.coveo.com/en/lcdf0264/) bindings to access the [Headless](https://docs.coveo.com/en/lcdf0493/) engine of your interface. <7> Subscribe to controller state changes. <8> (Optional) This line and the following are only relevant if your component needs to re-render when the [Atomic](https://docs.coveo.com/en/lcdf0264/) [i18n](https://www.i18next.com/) language changes (see [Localization](https://docs.coveo.com/en/atomic/latest/usage/atomic-localization/)). If your component doesn't use any strings or doesn't support multiple languages, ignore everything related to i18n. <9> Use the [`disconnectedCallback`](https://stenciljs.com/docs/component-lifecycle#disconnectedcallback) lifecycle method to unsubscribe controllers and possibly the i18n language change listener. <10> Leverage i18n to localize [facet](https://docs.coveo.com/en/198/) value captions. <11> Leverage i18n to localize the [facet](https://docs.coveo.com/en/198/) label. <12> Leverage the [Headless](https://docs.coveo.com/en/lcdf0493/) controller to dispatch the right actions to modify the controller state. <13> Render by inserting the content directly inside the HTML. ## Custom result template component example In custom result template components, you can leverage the `initializeBindings` method, as in other components. In addition, you can also leverage an exported `resultContext` method which retrieves the `result` from the parent component's rendered `atomic-result`. This lets you leverage result [item](https://docs.coveo.com/en/210/) [field](https://docs.coveo.com/en/200/) information. The following custom component example conditionally renders the author of a result, with a fallback to "Anonymous" if no author value is available. > **Note** > > This example is only intended for educational purposes. > In a real life scenario, use [result-field-condition](https://docs.coveo.com/en/atomic/latest/reference/result-template-components/atomic-field-condition/) and [atomic-result-text](https://docs.coveo.com/en/atomic/latest/reference/result-template-components/atomic-result-text/). ```html ``` <1> Set an initialization flag when implementing custom result list components, to avoid multiple initializations. <2> Retrieve the `result` object of the target result [item](https://docs.coveo.com/en/210/).