Custom panels
Add a full page of your own to Home Assistant, with a link in the sidebar and live access to the state of the home.
A panel is a full page in Home Assistant, like a dashboard, the map, or the settings. A custom panel is your own page: a custom element that gets the same hass object as everything else, and fills the whole screen next to the sidebar. Integrations use them for their own interfaces, and users can add them in YAML.
Create www/example-panel.js in your configuration folder:
class ExamplePanel extends HTMLElement {
set hass(hass) {
this._hass = hass;
this._render();
}
set narrow(narrow) {
this._narrow = narrow;
this._render();
}
set panel(panel) {
this._panel = panel;
this._render();
}
_render() {
if (!this._hass || !this._panel) {
return;
}
const count = Object.keys(this._hass.states).length;
this.innerHTML = `
<p>There are ${count} entities.</p>
<p>The screen is ${this._narrow ? "" : "not "}narrow.</p>
<pre>${JSON.stringify(this._panel.config, null, 2)}</pre>
`;
}
}
customElements.define("example-panel", ExamplePanel);Then register the panel in configuration.yaml, and restart Home Assistant:
panel_custom:
- name: example-panel
url_path: example
sidebar_title: Example panel
sidebar_icon: mdi:server
module_url: /local/example-panel.js
config:
hello: worldThe panel opens at /example, with a link in the sidebar.
| Option | Meaning |
|---|---|
name |
The tag name of your element. Required. |
url_path |
The URL of the panel. Defaults to name. Must be unique. |
sidebar_title |
The text in the sidebar. Without it, the panel is not in the sidebar. |
sidebar_icon |
The icon in the sidebar. Defaults to mdi:bookmark. |
module_url |
The URL of your JavaScript module. Set this one, js_url, or both: without either, the panel is not registered. |
js_url |
The URL of a classic JavaScript file. When you set both, the legacy build of the frontend uses this one, and the modern build module_url. |
config |
Anything you want to pass to the panel. It shows up as panel.config, next to a _panel_custom key that Home Assistant adds with the panel settings. |
require_admin |
Only show the panel to administrators. Defaults to false. |
embed_iframe |
Render the panel in an iframe, isolated from the rest of the frontend. Defaults to false. |
trust_external_script |
Load a script from another host without asking. Defaults to false, and then users are asked to confirm, because the script gets full access to Home Assistant. |
handle_safe_area |
Set to true when your panel handles the safe areas of a phone screen, like the notch, itself. Home Assistant then doesn't add its own padding around the panel. Defaults to false. |
An integration registers a custom panel from Python with async_register_panel() from the panel_custom integration. It takes the same options, but a few have other names: webcomponent_name for name, frontend_url_path for url_path, and trust_external for trust_external_script.
Home Assistant sets these properties on your element:
| Property | What it is |
|---|---|
hass |
The full state of Home Assistant. Set again on every change. See the hass object reference. |
narrow |
true when the panel should use a layout for narrow screens. |
route |
The current route: prefix is the URL of the panel, and path the rest of the URL. Use it for pages inside your panel. |
panel |
The panel information. The config option is in panel.config, together with the _panel_custom key. |
Your panel is responsible for its whole page, including a header and a way to open the sidebar on a narrow screen.
The frontend loads custom panels in both its modern and legacy builds. Define your element with a standard JavaScript class. Elements transpiled to ES5 functions are not supported.