# HTML component custom API

### Overview

Every **HTML code** component on a page exposes a JavaScript API via `window.FpsHtml_API`. This lets you programmatically control any HTML component from custom scripts — update content, show/hide, re-run embedded scripts, or call backend endpoints — all without a page reload.

### Setup: Component ID

For the API to work, the component must have a **Component ID** set in its settings (`comp_ID` field). Without it the component won't register itself in `window.FpsHtml_API`.

Set a short, unique string like `hero-block` or `promo-banner`.

### Accessing the API

The API is registered after the component mounts. Use the helper below to wait for it:

```javascript
function waitForHtmlAPI(compId, callback, timeout) {
  timeout = timeout || 5000;
  var start = Date.now();
  var check = function() {
    if (window.FpsHtml_API && window.FpsHtml_API[compId]) {
      callback(window.FpsHtml_API[compId]);
    } else if (Date.now() - start < timeout) {
      setTimeout(check, 100);
    } else {
      console.error('FpsHtml_API: component "' + compId + '" not found after ' + timeout + 'ms');
    }
  };
  check();
}
```

Then use it:

```javascript
waitForHtmlAPI('my-block', function(api) {
  api.setHtml('<p>Hello from API!</p>');
});
```

### API Reference

#### `getHtml()`

Returns the current HTML string of the component.

```javascript
var html = api.getHtml();
console.log(html); // '<p>Hello from API!</p>'
```

***

#### `setHtml(newHtml)`

Replaces the component's HTML content.

```javascript
api.setHtml('<h2>Updated content</h2><p>Fresh text here.</p>');
```

***

#### `rerender()`

Forces the component to re-execute all embedded `<script>` tags. Useful when you need scripts inside the HTML to run again without changing the content.

```javascript
api.rerender();
```

***

#### `show()`

Shows the component if it was hidden via `api.hide()`.

```javascript
api.show();
```

***

#### `hide()`

Hides the component programmatically. Does not affect the `isHidden` setting — just toggles visibility at runtime.

```javascript
api.hide();
```

***

#### `getData()`

Returns the full data object the component was initialized with (including `html`, `comp_ID`, `isHidden`, etc.).

```javascript
var data = api.getData();
console.log(data.comp_ID); // 'my-block'
```

***

#### `getElement()`

Returns the root DOM element wrapping the component. Useful for direct DOM manipulation.

```javascript
var el = api.getElement();
el.style.opacity = '0.5';
```

***

#### `callEndpoint(endpoint, method, body, params, callback)`

Makes an authenticated request to a backend endpoint. Works the same as `window.callEndpoint()` but scoped to this component's context.

**Parameters:**

| Parameter  | Type             | Description                                              |
| ---------- | ---------------- | -------------------------------------------------------- |
| `endpoint` | string           | API endpoint name (e.g. `'getItems'`)                    |
| `method`   | string           | HTTP method: `'GET'`, `'POST'`                           |
| `body`     | object\|FormData | Request body (ignored for GET)                           |
| `params`   | object           | URL query parameters                                     |
| `callback` | function         | `(status, data) => {}` — `status` is `'ok'` or `'error'` |

```javascript
api.callEndpoint('getStats', 'GET', null, { period: '30d' }, function(status, data) {
  if (status === 'ok') {
    api.setHtml('<p>Total: ' + data[0].total + '</p>');
  }
});
```

### Examples

#### Load data and render HTML on page load

```javascript
waitForHtmlAPI('stats-widget', function(api) {
  api.callEndpoint('getDashboardStats', 'GET', null, {}, function(status, data) {
    if (status === 'ok') {
      var item = data[0] || {};
      api.setHtml(
        '<div class="stats">' +
          '<span>Users: ' + item.users + '</span>' +
          '<span>Orders: ' + item.orders + '</span>' +
        '</div>'
      );
    } else {
      api.hide();
    }
  });
});
```

***

#### Control visibility from another HTML component

```javascript
// This script lives inside a different HTML component on the same page
document.getElementById('toggle-btn').addEventListener('click', function() {
  var api = window.FpsHtml_API && window.FpsHtml_API['promo-banner'];
  if (api) {
    api.hide();
  }
});
```

***

#### Update content on a button click

```javascript
waitForHtmlAPI('result-block', function(api) {
  document.getElementById('load-btn').addEventListener('click', function() {
    api.setHtml('<p>Loading...</p>');

    api.callEndpoint('fetchResult', 'POST', { id: '123' }, {}, function(status, data) {
      if (status === 'ok') {
        api.setHtml('<p>' + data[0].text + '</p>');
      } else {
        api.setHtml('<p>Error loading data.</p>');
      }
    });
  });
});
```

***

#### Re-run scripts after socket update

If you have scripts inside the HTML component that should re-execute when data refreshes via WebSocket, call `rerender()` after updating content:

```javascript
waitForHtmlAPI('chart-block', function(api) {
  api.callEndpoint('getChartData', 'GET', null, {}, function(status, data) {
    if (status === 'ok') {
      api.setHtml('<canvas id="myChart"></canvas><script>/* init chart with ' + JSON.stringify(data) + ' */<\/script>');
      api.rerender();
    }
  });
});
```

### Notes

* The API is registered after component mount. Always use `waitForHtmlAPI` (or a similar polling approach) rather than accessing `window.FpsHtml_API` directly.
* `hide()` / `show()` is runtime-only. The `isHidden` setting in the component config is a separate mechanism and takes precedence at initial render.
* If the component is removed from the page, its entry in `window.FpsHtml_API` is automatically deleted.
* All requests via `api.callEndpoint()` are authenticated the same way as `window.callEndpoint()`. See `CUSTOM_BROWSER_API.md` for details.


---

# 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://readme.directual.com/web-pages/components/html-code/html-component-custom-api.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.
