# Umbraco Controller

An Umbraco controller provides all the features of an Umbraco element within a separate class. Do this for architectural reasons or to reuse a feature across elements.

## Host Element

A Controller is assigned to a Host Element. This assignment may be indirect, since Controllers can host other Controllers.

The host element is a web component enhanced to host controllers. All [Umbraco Elements](/umbraco-cms/18.latest/extend-your-project/backoffice-extensions/foundation/umbraco-element.md) are controller hosts, as are all Umbraco controllers, allowing controllers to host other controllers.

To retrieve the controller’s host element, use the `getHostElement()` method.

## Element Life Cycle

Controllers can declare the following methods, which are triggered depending on the host element’s life cycle:

* `hostConnected()` — Called when the host element connects to the DOM.
* `hostDisconnected()` — Called when the host element disconnects from the DOM.
* `destroy()` — Called when the controller is taken out of commission.

Additionally, Umbraco Controllers implement a `getHostElement()` method, which enables any Controller to receive the Element that hosts the Controllers.

## Registration

A Controller should register itself with a given host. This is handled automatically when extending the `UmbControllerBase` class. The following example demonstrates a controller implementation:

```
import { UmbControllerBase } from '@umbraco-cms/backoffice/class-api';
import type { UmbControllerHost } from '@umbraco-cms/backoffice/controller-api';

export class MyOwnControllerImplementation extends UmbControllerBase {

    #secondsAlive = 0;

    constructor(host: UmbControllerHost) {
        // Parse the host to the base class, this will trigger the registration.
        super(host);
    }
    
    hostConnected() {
        // It's important to call the super method when overriding a method of the base class.
        super.hostConnected();
        this.#timer = setInterval(this.#onInterval, 1000)
    }
    
    hostDisconnected() {
        // It's important to call the super method when overriding a method of the base class.
        super.hostDisconnected();
        clearInterval(this.#timer);
    }
    
    #onInterval = () => {
        this.#secondsAlive++;
        console.log(`My own controller have been connected in ${this.#secondsAlive} seconds.`);
    }

    override destroy(): void {
        // It's important to call the super method when overriding a method of the base class.
        super.destroy();
        // We do not need to stop the timer in the Destroy method, because the hostDisconnected method is also called if connected and destroyed.
    }
}
```

If you don't like to extend the `UmbControllerBase`, then you can register a class as a controller as shown in the following example. Note that manual deregistration is required in this case.

```
export class MyOwnControllerImplementation {

    #host: UmbControllerHost;

    constructor(host: UmbControllerHost) {
        this.#host = host;
        this.#host.addUmbController(this);
    }
    
    override destroy(): void {
        this.#host.removeUmbController(this);
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.umbraco.com/umbraco-cms/18.latest/extend-your-project/backoffice-extensions/foundation/umbraco-controller.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
