# Unrestricted custom component

{% hint style="warning" %}
The feature is deprecated, please refer to [this article](https://docs.uibakery.io/concepts/custom-components-2.0) for information on building custom components in UI Bakery.
{% endhint %}

When you require a component not available in our Components list, you can develop it by utilizing the **unrestricted custom component**. With it, you can embed any HTML or JavaScript code without any constraints directly into any UI Bakery page.

{% hint style="success" %}
Unlike custom components, unrestricted custom components **are NOT contained within an iframe** and can be used for **displaying overlays, popups**, and other similar elements.
{% endhint %}

## Component anatomy

In contrast to custom components, unrestricted custom components are rendered on the same level as the rest of UI Bakery components.

{% hint style="warning" %}
We advise you to exercise caution while using this type of component since it may disrupt the UI Bakery page layout and styles and potentially access app data.
{% endhint %}

Here is an example of an unrestricted custom component:

<pre class="language-html"><code class="lang-html"><strong>&#x3C;!-- 3rd party scripts and styles -->
</strong>&#x3C;script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin>&#x3C;/script>
&#x3C;script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin>&#x3C;/script>
&#x3C;script src="https://unpkg.com/babel-standalone@6/babel.min.js">&#x3C;/script>

&#x3C;!-- root element where the component will be rendered -->
&#x3C;div class="root">&#x3C;/div>

&#x3C;!-- custom styles -->
&#x3C;style>
  .custom-component-container p { margin-top: 0 }
  .custom-component-container button { margin-bottom: 1rem }
  .custom-component-container {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
  }
&#x3C;/style>

&#x3C;!-- custom logic -->
&#x3C;script type="text/babel">
  function CustomComponent() {
    // receive data from UI Bakery
    const data = UB.useData();

    return (
      &#x3C;div className="custom-component-container">
        &#x3C;p>Data from UI Bakery: {data.title}&#x3C;/p>
        &#x3C;button onClick={() => UB.triggerEvent("Data from custom component")}>Trigger Event&#x3C;/button>
        &#x3C;input onChange={(event) => UB.updateValue(event.target.value)} placeholder="Set state">&#x3C;/input>
      &#x3C;/div>
    );
  }

  const Component = UB.connectReactComponent(CustomComponent);
  ReactDOM.render(&#x3C;Component />, UB.container.querySelector('.root'));

  // it's a good practice to destroy all resources you consumed in your custom component.
  UB.onDestroy(() => ReactDOM.unmountComponentAtNode( UB.container.querySelector('.root')));
&#x3C;/script>
</code></pre>

{% hint style="info" %}
UI Bakery will put all script tags with the <mark style="color:blue;">src</mark> attribute to the end of the head tag. All scripts with the same <mark style="color:blue;">src</mark> attributes will be loaded only once. I**f you remove a script, make sure to reload the page.**
{% endhint %}

## Passing data to a component

{% hint style="info" %}
The API and settings for the Unrestricted custom component are the same as those of the [Custom component](https://docs.uibakery.io/concepts/components/custom-component).
{% endhint %}

To pass data to your custom component you can use a component's **Data** property. You simply need to specify the JavaScript object that contains the necessary data, for example:

```javascript
{
  data: [1,2,3],
  display: 'only_new',
}
```

Additionally, you can pass data using **JS API** in your actions:

```javascript
ui.customComponent.setData({ ... })
```

* To access this data within the custom component, you can use:

```javascript
const data = UB.useData()
```

* You can also subscribe to data updates with the following code:

```javascript
UB.onData(data => {
    console.log('new data', data);
});
```

## Receiving data and triggering actions from a component

If your custom component produces events or needs to trigger an action, you can use the following code:

* ```javascript
  UB.updateValue('Data from custom component');
  ```

Use this code inside a component to set its value. Once executed, the new value will be available as {{`ui.customComponent.value}}`.

* ```javascript
  UB.triggerEvent('Data from custom component');
  ```

Use this code inside a component to trigger an action. You also need to subscribe your action to the **On Event** trigger of the custom component. Once the `UB.triggerEvent('data')` is executed, the assigned action will be triggered.

<figure><img src="https://837703843-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUX6zPRMFFK0yrTghj7cY%2Fuploads%2FNsPIjdMq0lrjQYzRaAaW%2FCleanShot%202024-12-16%20at%2015.54.08%402x-min.png?alt=media&#x26;token=b832d6eb-e6ad-4e2f-9a05-45f4146e98da" alt=""><figcaption></figcaption></figure>

The data supplied to the `triggerEvent()` function is available as the`{{ui.customComponent.value}}` variable as well as the `{{params}}` variable in the assigned action.
