# Development

Pages are developed, maintained and deployed by Ubidots **users** in order to create completely custom visualization that meet requirements otherwise not addressed natively by the platform.

A Page is structured around a specific set of files. These files not only determine the Page settings, for example, references to local or external CDN-exposed CSS and JavaScript (JS) libraries, but also define its logic and overall functionality. The file structure for a Page is outlined below:

```
├── manifest.toml
├── script.js
├── body.html
├── style.css
├── static
│   ├── some_files_or_folders  
```

{% hint style="warning" %}
Adhering to this file structure and including all the mentioned files is mandatory for the Page to function correctly and be able to be deployed.
{% endhint %}

{% hint style="info" %}
**Allowed file extensions in the static folder**

.csv, .css, .gif, .html, .ini, .jpeg, .jpg, .js, .json, .jsx, .log, .md, .mjs, .png, .rst, .svg, .ts, .tsv, .tsx, .toml, .txt, .webp, .xml, .yaml, .yml
{% endhint %}

## manifest.toml

The manifest file defines the Page's settings and references to local or external CSS and JS resources, that is, it outlines:

* Name of the page.
* Keywords.
* Description.
* Path to local files.
* Local and third party JS libraries.
* Local and third party CCS stylesheets.

The typical manifest file of a Page is composed by the below keys and values.

| Key                         | Type                    | Description                                                                                                                                                    |
| --------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name                        | String                  | Name of the page                                                                                                                                               |
| keywords                    | Comma-separated strings | This is added in a `<meta>` tag to the HTML document's `<head>`.                                                                                               |
| description                 | String                  | This is added to the HTML document's `<head>` tag within a `<meta>` tag.                                                                                       |
| static\_paths               | List of strings         | Paths to folders containing local files.                                                                                                                       |
| js\_libraries               | List of sets            | It references local JS files. These files are included with a `<script>` tag in the HTML document's `<head>`.                                                  |
| js\_thirdparty\_libraries   | List of sets            | It references CDN-based JS libraries. These files are included with a `<script>` tag in the HTML document's `<head>`.                                          |
| css\_libraries              | List of sets            | It references local CSS stylesheets. These files are included with a `<link rel="stylesheet">` tag in the HTML document's `<head>`.                            |
| css\_thirdparty\_libraries  | List of sets            | It references CDN-based CSS stylesheets. These files are included with a `<link rel="stylesheet">` tag in the HTML document's `<head>`.                        |
| link\_libraries             | List of sets            | It references local resources. These files are included with a [`<link>`](https://www.w3schools.com/tags/tag_link.asp) tag in the HTML document's `<head>`.    |
| link\_thirdparty\_libraries | List of sets            | It references external resources. These files are included with a [`<link>`](https://www.w3schools.com/tags/tag_link.asp) tag in the HTML document's `<head>`. |

With that in mind, a manifest file looks like this:

{% hint style="warning" %}
The manifest.toml file most start with the `[page]` section header.
{% endhint %}

```toml
[page]
name = "Page name"
keywords = "test,validation"
description = "Page for testing purposes."
static_paths = ["static"]

js_libraries = [{src="script.js", type="module", defer="", crossorigin=""}]
js_thirdparty_libraries = [
    {src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"},
    {src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"}
]

css_libraries = [{href="style.css", crossorigin=""}]
css_thirdparty_libraries = []

link_libraries = [{href="static/style_link.css", type="font", crossorigin=""}]
link_thirdparty_libraries = []
```

The below shows how Ubidots interprets the Page's name, keywords and description, and adds it to the Page's HTML document's `<head>` automatically.

```html
<head>
     <title>Page name</title>
     <meta name="keywords" content="test,validation"/>
     <meta name="description" content="Page for testing purposes."/>
</head>
```

Read the following section to learn about how Ubidots interprets the libraries keys.

### Libraries syntax

This applies to the "List of sets" type keys. These keys hold list values, where each element has either of the below forms:

<table><thead><tr><th width="235">Key</th><th width="325">Form</th><th>Description</th></tr></thead><tbody><tr><td><p>– js_libraries</p><p>– js_thirdparty_libraries</p></td><td><pre><code>{src=&#x3C;URL|path>, [ATTRIBUTES]}
</code></pre></td><td><code>[ATTRIBUTES]</code> can be any of HTML's <a href="https://www.w3schools.com/tags/tag_script.asp"><code>&#x3C;script></code></a> tag.</td></tr><tr><td><p>– css_libraries</p><p>– css_thirdparty_libraries</p><p>– link_libraries</p><p>– link_thirdparty_libraries</p></td><td><pre><code>{href=&#x3C;URL|path>, [ATTRIBUTES]}
</code></pre></td><td><code>[ATTRIBUTES]</code> can be any of HTML's <a href="https://www.w3schools.com/tags/tag_link.asp"><code>&#x3C;link></code></a> tag.</td></tr></tbody></table>

The way Ubidots interprets these libraries keys and adds it to the Page's HTML document's `<head>` is as follows:

```html
<head>
    <!-- js_libraries
    TOML: {src="script.js", type="module", defer="", crossorigin=""}
    Translates to:
    -->
    <script src="UBIDOTS_CDN_URL/script.js" type="module" defer crossorigin></script>
    
    <!-- js_thirdparty_libraries
    TOML: {src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"}
    Translates to:
    -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
    
    <!-- css_libraries
    TOML: {href="style.css", crossorigin=""}
    Translates to:
    -->
    <link href="UBIDOTS_CDN_URL/style.css" crossorigin rel="stylesheet"/>
    
    <!-- css_thirdparty_libraries
    TOML: {href="https://fonts.googleapis.com/css?family=Roboto:300i,400&display=swap", crossorigin=""}
    Translates to:
    -->
    <link href="https://fonts.googleapis.com/css?family=Roboto:300i,400&display=swap" crossorigin rel="stylesheet"/>
    
    <!-- link_libraries
    TOML: {href="static/style_link.css", type="font", crossorigin=""}
    Translates to:
    -->
    <link href="UBIDOTS_CDN_URL/static/style_link.css" type="font" crossorigin rel="stylesheet"/>
    
    <!-- link_thirdparty_libraries
    TOML: {href="https://fonts.googleapis.com/css?family=Roboto:310i,410&display=swap", type="font", crossorigin=""}
    Translates to:
    -->
    <link href="https://fonts.googleapis.com/css?family=Roboto:310i,410&display=swap" type="font" crossorigin rel="stylesheet"/>
</head>
```

## script.js

This file holds the JS logic of the Page. It can:

* Use the `js_libraries` and `js_thirdparty_libraries` specified in the `manifest.toml` file.
* It has access to [Ubidots built-in JS library](https://dev.ubidots.com/dashboards-and-widgets/html-canvas/built-in-library).

## body.html

This is the HTML body of the page. You should only include the contents of the `<body>`. Ubidots will then put all of it within the actual Page's body. For example:

Your code:

```html
<div id="main"></div>
```

Loaded in the page:

```html
<body>
    <div id="main"></div>
</body>
```

{% hint style="danger" %}
Your body.html file should not include the \<head> as Ubidots creates it using the manifest.toml file.
{% endhint %}

## style.css

This the main stylesheet of your page, although you can import more either from local files located in the "static\_path" folder, or from external resources.

## static folder

In this folder, you can upload additional CSS or JS files, more folders or even other types file. This serves as a place to include proprietary libraries or resources such as fonts, icon, images, etc., that are needed for the page rendering.\
These files can be used in 2 ways within the Page:

1. By being referenced in the `manifest.toml` file, in which case Ubidots will import them appropriately as described in the [Libraries syntax](#libraries-syntax) section.
2. By accessing the files using the public `staticURL` of the page. See more below.

Accessing files in the `/static` folder (or other folder referenced in the `manifest.toml`) from the `script.js` is done as follows:

```
const staticPageUrl = window.staticUrl;
const imageUrl = `${staticPageUrl}/<path>/<fileName>.<extension>`;
```

Where `<path>` is the path referenced in the manifest.toml, for example "static", and then `<fileName>` and `<extension>` are the specific file and extension within the "static" folder.

{% hint style="info" %}
**Allowed file extensions**

.csv, .css, .gif, .html, .ini, .jpeg, .jpg, .js, .json, .jsx, .log, .md, .mjs, .png, .rst, .svg, .ts, .tsv, .tsx, .toml, .txt, .webp, .xml, .yaml, .yml
{% endhint %}
