Skip to content
Stand with Ukraine flag

HTML Container

  • Widget
  • v1.0.0
  • Sep 1, 2026
  • MIT license
  • v4.2+ | Built-in
HTML Container

Configurable HTML, CSS and JavaScript widget with access to the Widget API via WidgetContext and the ability to load external resources or modules. Supports two modes: plain HTML (regular HTML/JS bound to the widget container) and Angular (Angular template with bound variables and functions). Use for custom complex visualizations or actions when system widgets are not enough.

Widget Type
  • Static
Category
  • Cards & Info
Use Cases
  • Industrial Automation
  • Smart Building
  • SCADA

Who it’s for

Developers who have hit the end of what the widget library covers and need to build the visualization themselves — a bespoke diagram, a third-party charting library, a multi-step control panel with its own logic. The requirement is not another layout option; it is code, running inside the dashboard, with access to the widget’s data and actions.

What it does

The HTML Container runs HTML, CSS and JavaScript you supply inside a widget tile, with the Widget API available through the widget context. In plain mode the JavaScript receives the container element and wires itself to the DOM directly; in Angular mode the markup is an Angular template bound to variables and functions the script exposes, so *ngIf, *ngFor and Angular Material components work as they do elsewhere in the platform.

  • Two modes for two kinds of work — plain HTML for a library that wants a DOM node handed to it, Angular for markup that should react to bound state without manual DOM updates.
  • The Widget API is in reach — subscriptions, entity data, RPC and dashboard actions are all available through the widget context, so a container is a real widget rather than a decorative panel.
  • External scripts and stylesheets load by URL, with a flag marking a resource as an ES module, which is how a charting or 3D library gets in.
  • The widget owns its lifecycle, so a container can subscribe to what it needs rather than being limited to the datasource the widget config declares.
  • The HTML Container is the fallback, not the default: anything an existing widget already does is faster to configure and cheaper to maintain there than to rebuild here.

How to set up

Data keys

The HTML Container takes datasources and keys like any widget, and the script decides what to do with them.

KeyRoleTypeDescription
AnyWhatever the script readsTimeseriesAttributes work equally well. Keys declared in the widget config arrive through the widget context; a container may also create its own subscriptions instead of, or in addition to, the declared ones.

Content

SettingDefaultEffect
TypePlain HTMLPlain HTML binds the script to the container element; Angular treats the markup as a template with bound variables and functions
HTMLEmptyThe markup rendered inside the tile
CSSEmptyStyles for that markup, scoped to this widget
JavaScriptEmptyThe widget’s code, receiving the widget context
ResourcesEmptyExternal JavaScript or CSS loaded by URL; Is extension marks a URL as an ES module

Pick the mode before writing anything — moving markup between plain and Angular later means rewriting how it updates, not just where it lives. Add external resources first and confirm they load, since a missing library fails silently inside a container that otherwise renders.

How to customize

  • To switch the rendering model — change Type between Plain HTML and Angular; the markup and the script are written differently in each.
  • To pull in a library — add its URL under Resources, and set Is extension when the URL is an ES module rather than a classic script.
  • To restyle without touching the markup — edit the CSS box, which is scoped to this widget and will not affect the rest of the dashboard.
  • To respond to dashboard actions — use the widget context inside the JavaScript box rather than binding handlers in the markup, which keeps the behavior in one place.

Tips

  • Build the container against static sample data first and connect the real subscription last. Layout bugs and subscription bugs look identical from the outside — an empty tile — and separating them saves most of the debugging.
  • Pin an exact version in every resource URL. A container that silently follows a library’s latest release works until the day the library ships a breaking change, and the dashboard it lives on will have been untouched for months by then.

Share Your Widget with the Community

Built a custom widget? Export it as a JSON from ThingsBoard and publish it to the IoT Hub through a simple 4-step wizard (Upload, Listing, Readme, Review & Submit). Share it with thousands of ThingsBoard developers worldwide and get featured in the catalog.