> For the complete documentation index, see [llms.txt](https://docs.xibosignage.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xibosignage.com/developer/player-control/data-connectors/hello-world.md).

# Hello World

In this example we will create a data connector and a simple layout which shows its data using an embedded widget.

{% stepper %}
{% step %}

### Part 1 - Data Connector

Log into your CMS and navigate to the DataSet page. Create a new DataSet and give it a name, e.g. “Hello World”. Tick the “Real time?” checkbox, then a dropdown will appear. Choose “User-Defined JavaScript” and Save.

[![](/files/aaff9095eb2c54abdf72a60d62b974a05ca4c296)](https://account.xibosignage.com/img/developer/040d41b1bffdddabe44229dfefe95e5a7669502e_2_529x500.png)

We could configure columns to match our data structure and have those available via Layout Elements, but for now we will skip this step.

Use the row menu on the “Hello World” DataSet and select “View Data Connector”. You will be taken to the data connector page:

[![](/files/7e35af0a4bb687a1f2220bb2e3d41ffbe2d6539e)](https://account.xibosignage.com/img/developer/39845cddb458e4b1c8dadc51300194c13fbf286e_2_690x404.png)

This is a new data connector so we have been given the onInit function ready to fill in. For this example we are going to simulate a connection to a sensor which gives us an integer number we want to show on our display in real time.

We will start by putting the following code inside our onInit function:

{% code title="data-connector.js" %}

```javascript
window.onInit = function() {
  setInterval(function() {
    xiboDC.setData('sensor', (Math.floor(Math.random() * 100) + 1), {
      done: function() {
        xiboDC.notifyHost('sensor');
      }
    });
  }, 1000);
}
```

{% endcode %}

We are using the `xiboDC` library to set data for a key called `sensor`, and then a normal JavaScript interval function to update that every second.

We have also provided a `done` function to `setData` which will be called when the player has updated its internal database. Once this is done we choose to `notifyHost` for the same `sensor` key. This will cause the player to run through all currently active layouts and give them the option to respond to new data.

Press Save.

After pressing save you will see that the “Logs” tab on the right hand side starts to update with a message saying that the notify has been called for the sensor key:

[![](/files/8b029fc525427ee0bb750e698e958c68bad0fa79)](https://account.xibosignage.com/img/developer/f73c81ecfe03b95fafb27f11ed770aa81483096b.png)

On the “Other Data” tab you will also see that the “sensor” key gets updated once per second with a new random integer. E.g:

[![](/files/066359789bfecf4e61c954ba087316f911f5183d)](https://account.xibosignage.com/img/developer/42233e926bd519362b04fd8815e3331c97b1af5c_2_690x201.png)
{% endstep %}

{% step %}

### Part 2 - Layout

Open a new tab, navigate to the Layouts page and Add Layout. The Layout Editor will open.

Using the toolbox, add an Embedded widget to your layout. For ease the example sets the layout background colour to pink and moves the Embedded widget to the right hand side near the properties panel.

[![](/files/678f86df67fb71a07a626ab8302d3f1ba16e4050)](https://account.xibosignage.com/img/developer/65f779db7ffc0e49ee66ad5bdb4420cf499176e9_2_330x500.png)

In the “HTML” section, add a `div` for the random number to appear inside:

{% code title="embedded-widget.html" %}

```html
<div id="sensor">No data</div>
```

{% endcode %}

Add a style so the number is visible:

{% code title="embedded-widget.css" %}

```css
#sensor {
   font-size: 50px;
}
```

{% endcode %}

The layout should look like this:

[![](/files/eea48c9ffa08e425ba106d862d8c2b58036b8c79)](https://account.xibosignage.com/img/developer/c642c4a62b4ea9f0187a3ed0514e1b77120f2d2b_2_323x500.png)

Now add JavaScript to tell the widget we’re interested in updates to the `sensor` key and render those updates:

{% code title="embedded-widget.js" %}

```javascript
xiboIC.registerNotifyDataListener(function(dataKey) {
  if (dataKey !== 'sensor') {
    return;
  }
  xiboIC.getData('sensor', {
    done: function(code, data) {
      $('#sensor').html(data);
    }
  });
});
```

{% endcode %}

We are using the `xiboIC` library to register our interest in data changes, and then we compare the dataKey against the `sensor` key we want.

If we have an update to that key, we use `xiboIC.getData` for that key, and set the result as the contents of our sensor div.

Your layout now looks like this:

[![](/files/e43a9dc0e36ae6dc5e01e1dab2c2a4ec559f0ba7)](https://account.xibosignage.com/img/developer/f5d6f90390ffa6121a0d720a4031f8712dfe4ad6_2_357x500.png)

When testing in the CMS, new data will only be received if the Data Connector View page is open in another tab. On the player it will only be received if your Data Connector is active in the schedule.
{% endstep %}
{% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.xibosignage.com/developer/player-control/data-connectors/hello-world.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
