# Dashboard 2.0 icons in html-template-node

**URL:** <https://discourse.nodered.org/t/dashboard-2-0-icons-in-html-template-node/98506>\
**Category:** Dashboard\
**Tags:** dashboard-2\
**Created:** [5 August 2025 10:03 UTC](https://discourse.nodered.org/t/dashboard-2-0-icons-in-html-template-node/98506 "2025-08-05T10:03:00Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![rewegit](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rewegit/32/4778_2.png) [@rewegit](https://discourse.nodered.org/u/rewegit)\
**Post date:** [5 August 2025 10:03 UTC](https://discourse.nodered.org/t/dashboard-2-0-icons-in-html-template-node/98506/1 "2025-08-05T10:03:00Z")

</div>

I am trying to create my own button-toggle component with an html-template-node.The logic works so far. However, I can't get it to work with icons. They are not rendered for me.The icons work fine in a standard Dashboard 2.0 button-group-node.How do I integrate them correctly into the html-template-node?

Example

```flows
[
    {
        "id": "155d7a767c816aa9",
        "type": "inject",
        "z": "23f984cab29f3522",
        "name": "Set Initial States",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "{\"power\":true,\"light\":false,\"fan\":false,\"settings\":true}",
        "payloadType": "json",
        "x": 90,
        "y": 140,
        "wires": [
            [
                "d8f5ad2451889c9a"
            ]
        ]
    },
    {
        "id": "d8f5ad2451889c9a",
        "type": "ui-template",
        "z": "23f984cab29f3522",
        "group": "ui-group-1",
        "page": "",
        "ui": "",
        "name": "Toggle Button Group",
        "order": 1,
        "width": "6",
        "height": "3",
        "head": "<link href=\"https://fonts.googleapis.com/icon?family=Material+Icons\" rel=\"stylesheet\">",
        "format": "<template>\n <div class=\"toggle-widget-container\">\n <div :style=\"containerStyles\" class=\"toggle-button-group\">\n <div \n v-for=\"(button, index) in buttons\" \n :key=\"button.name\"\n :class=\"['toggle-btn', { \n 'active': toggleStates[button.name], \n 'first': index === 0, \n 'last': index === buttons.length - 1 \n }]\"\n :style=\"getButtonStyle(button.name, index)\"\n @click=\"toggleButton(button.name)\"\n @mouseenter=\"showTooltip(button.name, $event)\"\n @mouseleave=\"hideTooltip\"\n :title=\"button.tooltip\"\n >\n <i :class=\"getIconClass(button.icon)\" class=\"material-icons\">{{ getIconName(button.icon) }}</i>\n </div>\n </div>\n \n <div v-if=\"tooltipVisible\" class=\"tooltip\" :style=\"tooltipStyle\">\n {{ getTooltipText(tooltipVisible) }}\n </div>\n </div>\n</template>\n\n\n<script>\nexport default {\n data() {\n return {\n toggleStates: {\n 'power': false,\n 'light': false,\n 'fan': false,\n 'settings': false\n },\n config: {\n border: 1,\n size: '35px',\n position: 'bottom-right',\n distance: 5,\n color: {\n active: '#2196F3',\n inactive: '#FFFFFF',\n hover: '#BBDEFB',\n border: '#E0E0E0'\n }\n },\n buttons: [\n { name: 'config', icon: 'hammer-screwdriver', tooltip: 'cinfig' },\n { name: 'charts', icon: 'chart-line', tooltip: 'charts' },\n { name: 'temperature', icon: 'temperature-celsius', tooltip: 'Temperature Control' },\n { name: 'humidifier', icon: 'air-humidifier', tooltip: 'humidifier Control' }\n],\n tooltipVisible: null,\n tooltipStyle: {}\n };\n },\n computed: {\n containerStyles() {\n const pos = this.config.position || 'bottom-right';\n const distance = `${this.config.distance || 5}px`;\n \n let positioning = {};\n \n if (pos.includes('bottom')) {\n positioning.bottom = distance;\n } else if (pos.includes('top')) {\n positioning.top = distance;\n }\n \n if (pos.includes('right')) {\n positioning.right = distance;\n } else if (pos.includes('left')) {\n positioning.left = distance;\n }\n \n return {\n position: 'absolute',\n display: 'flex',\n zIndex: 1000,\n ...positioning\n };\n }\n },\n methods: {\n toggleButton(buttonName) {\n const newState = !this.toggleStates[buttonName];\n this.toggleStates[buttonName] = newState;\n \n // Send message to Node-RED\n this.send({\n payload: {\n [buttonName]: newState\n },\n timestamp: Date.now()\n });\n },\n \n getButtonStyle(buttonName, index) {\n const size = this.config.size || '35px';\n const border = this.config.border || 1;\n const colors = this.config.color || {\n active: '#2196F3',\n inactive: '#FFFFFF',\n hover: '#BBDEFB',\n border: '#E0E0E0'\n };\n \n const isActive = this.toggleStates[buttonName];\n const isFirst = index === 0;\n const isLast = index === this.buttons.length - 1;\n \n let backgroundColor = colors.inactive;\n let textColor = '#666';\n \n if (isActive) {\n backgroundColor = colors.active;\n textColor = 'white';\n }\n \n return {\n width: size,\n height: size,\n backgroundColor: backgroundColor,\n color: textColor,\n border: `${border}px solid ${colors.border}`,\n borderRight: isLast ? `${border}px solid ${colors.border}` : 'none',\n borderRadius: '0',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n userSelect: 'none',\n boxSizing: 'border-box'\n };\n },\n \n getIconClass(icon) {\n return 'material-icons';\n },\n \n getIconName(icon) {\n return icon;\n },\n \n getTooltipText(buttonName) {\n const button = this.buttons.find(b => b.name === buttonName);\n return button ? button.tooltip : '';\n },\n \n showTooltip(buttonName, event) {\n this.tooltipVisible = buttonName;\n \n const rect = event.target.getBoundingClientRect();\n this.tooltipStyle = {\n position: 'fixed',\n top: (rect.top - 35) + 'px',\n left: (rect.left + rect.width / 2) + 'px',\n transform: 'translateX(-50%)',\n backgroundColor: 'rgba(0, 0, 0, 0.8)',\n color: 'white',\n padding: '6px 10px',\n borderRadius: '4px',\n fontSize: '12px',\n whiteSpace: 'nowrap',\n zIndex: 10001,\n pointerEvents: 'none'\n };\n },\n \n hideTooltip() {\n this.tooltipVisible = null;\n }\n },\n \n watch: {\n msg: {\n handler(newMsg) {\n if (newMsg && newMsg.payload) {\n // Update states from incoming message\n Object.assign(this.toggleStates, newMsg.payload);\n }\n \n if (newMsg && newMsg.config) {\n // Update configuration from incoming message\n Object.assign(this.config, newMsg.config);\n }\n \n if (newMsg && newMsg.buttons) {\n // Update button definitions from incoming message\n this.buttons = newMsg.buttons;\n \n // Initialize states for new buttons\n newMsg.buttons.forEach(button => {\n if (!(button.name in this.toggleStates)) {\n this.$set(this.toggleStates, button.name, false);\n }\n });\n }\n },\n deep: true\n }\n }\n}\n</script>\n\n<style scoped>\n.toggle-widget-container {\n position: relative;\n height: 100%;\n width: 100%;\n}\n\n.toggle-button-group {\n display: flex;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n}\n\n.toggle-btn {\n transition: all 0.2s ease;\n}\n\n.toggle-btn:hover {\n background-color: #BBDEFB !important;\n z-index: 1;\n}\n\n.toggle-btn.active:hover {\n background-color: #1976D2 !important;\n}\n\n.tooltip {\n position: fixed;\n background-color: rgba(0, 0, 0, 0.8);\n color: white;\n padding: 6px 10px;\n border-radius: 4px;\n font-size: 12px;\n white-space: nowrap;\n z-index: 10001;\n pointer-events: none;\n}\n\n.material-icons {\n font-size: 18px;\n line-height: 1;\n}\n</style>",
        "storeOutMessages": true,
        "passthru": false,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 300,
        "y": 200,
        "wires": [
            [
                "422345191feb1813"
            ]
        ]
    },
    {
        "id": "422345191feb1813",
        "type": "debug",
        "z": "23f984cab29f3522",
        "name": "Toggle Output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 520,
        "y": 200,
        "wires": []
    },
    {
        "id": "ui-group-1",
        "type": "ui-group",
        "name": "Toggle Button Group",
        "page": "ui-page-1",
        "width": "6",
        "height": "1",
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": true,
        "disabled": false
    },
    {
        "id": "ui-page-1",
        "type": "ui-page",
        "name": "Test Page",
        "ui": "1f09dc2ae6515591",
        "path": "/toggle-test",
        "icon": "home",
        "layout": "grid",
        "theme": "ui-theme-1",
        "order": 2,
        "className": "",
        "visible": true,
        "disabled": false
    },
    {
        "id": "1f09dc2ae6515591",
        "type": "ui-base",
        "name": "My Dashboard 2.0",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "temporary",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "ui-theme-1",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094ce",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "75ec18fe22e66bed",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.26.0"
        }
    }
]

```

---

<div class="post-metadata">

**Author:** ![Buckskin](https://avatars.discourse-cdn.com/v4/letter/b/b9e5f3/32.png) [@Buckskin](https://discourse.nodered.org/u/Buckskin)\
**Post date:** [5 August 2025 13:46 UTC](https://discourse.nodered.org/t/dashboard-2-0-icons-in-html-template-node/98506/2 "2025-08-05T13:46:50Z")

</div>

I imported your flow but all I got displayed was a blur of overwritten text.

This is a basic template button with icon. `btnBasic` & `iconBasic` classes just define the sizes, the two `:class` definitions just determine the colour. In this particular button the button text is above the icon, but I think for your purposes you are only interested in the `<v-icon></v-icon>` line

I vary the icon dependant on switch toggle by using `{{iconImage}}`, instead of a fixed image, and then computing the image required (for example` ['mdi-light-switch-off', 'mdi-light-switch']`)

```auto
        <v-btn class = "btnBasic" :class = "btnClass" stacked @click="changeState()">
            {{btnText}}
            <v-icon class = "iconBasic" :class = "iconClass" >mdi-lightbulb-variant-outline</v-icon

        </v-btn>

```

---

<div class="post-metadata">

**Author:** ![Buckskin](https://avatars.discourse-cdn.com/v4/letter/b/b9e5f3/32.png) [@Buckskin](https://discourse.nodered.org/u/Buckskin)\
**Post date:** [5 August 2025 15:22 UTC](https://discourse.nodered.org/t/dashboard-2-0-icons-in-html-template-node/98506/3 "2025-08-05T15:22:06Z")

</div>

Apologies, I realised what your problem was, Please find attached edited copy of your ui-template node. Changes are shown as v1.1

```auto
[{"id":"155d7a767c816aa9","type":"inject","z":"506727cd93754bdb","name":"Set Initial States","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"{\"power\":true,\"light\":false,\"fan\":false,\"settings\":true}","payloadType":"json","x":900,"y":1740,"wires":[["d8f5ad2451889c9a"]]},{"id":"d8f5ad2451889c9a","type":"ui-template","z":"506727cd93754bdb","group":"b93577c7977b9d29","page":"","ui":"","name":"Toggle Button Group","order":1,"width":"6","height":"3","head":"<link href=\"https://fonts.googleapis.com/icon?family=Material+Icons\" rel=\"stylesheet\">","format":"<template>\n <div class=\"toggle-widget-container\">\n <div :style=\"containerStyles\" class=\"toggle-button-group\">\n <div \n v-for=\"(button, index) in buttons\" \n :key=\"button.name\"\n :class=\"['toggle-btn', { \n 'active': toggleStates[button.name], \n 'first': index === 0, \n 'last': index === buttons.length - 1 \n }]\"\n :style=\"getButtonStyle(button.name, index)\"\n @click=\"toggleButton(button.name)\"\n @mouseenter=\"showTooltip(button.name, $event)\"\n @mouseleave=\"hideTooltip\"\n :title=\"button.tooltip\"\n >\n <v-icon :class=\"getIconClass()\">{{getIconName(index)}}</v-icon> <!-- v1.1 -->\n </div>\n </div>\n \n <div v-if=\"tooltipVisible\" class=\"tooltip\" :style=\"tooltipStyle\">\n {{ getTooltipText(tooltipVisible) }}\n </div>\n </div>\n</template>\n\n\n<script>\nexport default {\n data() {\n return {\n toggleStates: {\n 'power': false,\n 'light': false,\n 'fan': false,\n 'settings': false\n },\n config: {\n border: 1,\n size: '35px',\n position: 'bottom-right',\n distance: 5,\n color: {\n active: '#2196F3',\n inactive: '#FFFFFF',\n hover: '#BBDEFB',\n border: '#E0E0E0'\n }\n },\n buttons: [\n { name: 'config', icon: 'mdi-hammer-screwdriver', tooltip: 'Config' }, // v1.1 \n { name: 'charts', icon: 'mdi-chart-line', tooltip: 'charts' }, // v1.1\n { name: 'temperature', icon: 'mdi-temperature-celsius', tooltip: 'Temperature Control' }, // v1.1\n { name: 'humidifier', icon: 'mdi-air-humidifier', tooltip: 'Humidifier Control' } // v1.1\n],\n tooltipVisible: null,\n tooltipStyle: {}\n };\n },\n computed: {\n containerStyles() {\n const pos = this.config.position || 'bottom-right';\n const distance = `${this.config.distance || 5}px`;\n \n let positioning = {};\n \n if (pos.includes('bottom')) {\n positioning.bottom = distance;\n } else if (pos.includes('top')) {\n positioning.top = distance;\n }\n \n if (pos.includes('right')) {\n positioning.right = distance;\n } else if (pos.includes('left')) {\n positioning.left = distance;\n }\n \n return {\n position: 'absolute',\n display: 'flex',\n zIndex: 1000,\n ...positioning\n };\n }\n },\n methods: {\n toggleButton(buttonName) {\n const newState = !this.toggleStates[buttonName];\n this.toggleStates[buttonName] = newState;\n \n // Send message to Node-RED\n this.send({\n payload: {\n [buttonName]: newState\n },\n timestamp: Date.now()\n });\n },\n \n getButtonStyle(buttonName, index) {\n const size = this.config.size || '35px';\n const border = this.config.border || 1;\n const colors = this.config.color || {\n active: '#2196F3',\n inactive: '#FFFFFF',\n hover: '#BBDEFB',\n border: '#E0E0E0'\n };\n \n const isActive = this.toggleStates[buttonName];\n const isFirst = index === 0;\n const isLast = index === this.buttons.length - 1;\n \n let backgroundColor = colors.inactive;\n let textColor = '#666';\n \n if (isActive) {\n backgroundColor = colors.active;\n textColor = 'white';\n }\n \n return {\n width: size,\n height: size,\n backgroundColor: backgroundColor,\n color: textColor,\n border: `${border}px solid ${colors.border}`,\n borderRight: isLast ? `${border}px solid ${colors.border}` : 'none',\n borderRadius: '0',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'all 0.2s ease',\n userSelect: 'none',\n boxSizing: 'border-box'\n };\n },\n \n getIconClass(icon) {\n return 'material-icons';\n },\n \n getIconName(index) { // v1.1\n return this.buttons[index].icon // v1.1\n },\n \n getTooltipText(buttonName) {\n const button = this.buttons.find(b => b.name === buttonName);\n return button ? button.tooltip : '';\n },\n \n showTooltip(buttonName, event) {\n this.tooltipVisible = buttonName;\n \n const rect = event.target.getBoundingClientRect();\n this.tooltipStyle = {\n position: 'fixed',\n top: (rect.top - 35) + 'px',\n left: (rect.left + rect.width / 2) + 'px',\n transform: 'translateX(-50%)',\n backgroundColor: 'rgba(0, 0, 0, 0.8)',\n color: 'white',\n padding: '6px 10px',\n borderRadius: '4px',\n fontSize: '12px',\n whiteSpace: 'nowrap',\n zIndex: 10001,\n pointerEvents: 'none'\n };\n },\n \n hideTooltip() {\n this.tooltipVisible = null;\n }\n },\n \n watch: {\n msg: {\n handler(newMsg) {\n if (newMsg && newMsg.payload) {\n // Update states from incoming message\n Object.assign(this.toggleStates, newMsg.payload);\n }\n \n if (newMsg && newMsg.config) {\n // Update configuration from incoming message\n Object.assign(this.config, newMsg.config);\n }\n \n if (newMsg && newMsg.buttons) {\n // Update button definitions from incoming message\n this.buttons = newMsg.buttons;\n \n // Initialize states for new buttons\n newMsg.buttons.forEach(button => {\n if (!(button.name in this.toggleStates)) {\n this.$set(this.toggleStates, button.name, false);\n }\n });\n }\n },\n deep: true\n }\n }\n}\n</script>\n\n<style scoped>\n.toggle-widget-container {\n position: relative;\n height: 100%;\n width: 100%;\n}\n\n.toggle-button-group {\n display: flex;\n box-shadow: 0 1px 3px rgba(0,0,0,0.1);\n}\n\n.toggle-btn {\n transition: all 0.2s ease;\n}\n\n.toggle-btn:hover {\n background-color: #BBDEFB !important;\n z-index: 1;\n}\n\n.toggle-btn.active:hover {\n background-color: #1976D2 !important;\n}\n\n.tooltip {\n position: fixed;\n background-color: rgba(0, 0, 0, 0.8);\n color: white;\n padding: 6px 10px;\n border-radius: 4px;\n font-size: 12px;\n white-space: nowrap;\n z-index: 10001;\n pointer-events: none;\n}\n\n.material-icons {\n font-size: 18px;\n line-height: 1;\n}\n</style>","storeOutMessages":true,"passthru":false,"resendOnRefresh":true,"templateScope":"local","className":"","x":1110,"y":1740,"wires":[["422345191feb1813"]],"info":"<template>\r\n <div class=\"toggle-widget-container\">\r\n <div :style=\"containerStyles\" class=\"toggle-button-group\">\r\n <div \r\n v-for=\"(button, index) in buttons\" \r\n :key=\"button.name\"\r\n :class=\"['toggle-btn', { \r\n 'active': toggleStates[button.name], \r\n 'first': index === 0, \r\n 'last': index === buttons.length - 1 \r\n }]\"\r\n :style=\"getButtonStyle(button.name, index)\"\r\n @click=\"toggleButton(button.name)\"\r\n @mouseenter=\"showTooltip(button.name, $event)\"\r\n @mouseleave=\"hideTooltip\"\r\n :title=\"button.tooltip\"\r\n >\r\n <i :class=\"getIconClass(button.icon)\" class=\"material-icons\">{{ getIconName(button.icon) }}</i>\r\n <v-icon class=\"material-icons\" >'mdi-hammer-screwdriver'</v-icon>\r\n </div>\r\n </div>\r\n \r\n <div v-if=\"tooltipVisible\" class=\"tooltip\" :style=\"tooltipStyle\">\r\n {{ getTooltipText(tooltipVisible) }}\r\n </div>\r\n </div>\r\n</template>\r\n\r\n\r\n<script>\r\nexport default {\r\n data() {\r\n return {\r\n toggleStates: {\r\n 'power': false,\r\n 'light': false,\r\n 'fan': false,\r\n 'settings': false\r\n },\r\n config: {\r\n border: 1,\r\n size: '35px',\r\n position: 'bottom-right',\r\n distance: 5,\r\n color: {\r\n active: '#2196F3',\r\n inactive: '#FFFFFF',\r\n hover: '#BBDEFB',\r\n border: '#E0E0E0'\r\n }\r\n },\r\n buttons: [\r\n { name: 'config', icon: 'hammer-screwdriver', tooltip: 'cinfig' },\r\n { name: 'charts', icon: 'chart-line', tooltip: 'charts' },\r\n { name: 'temperature', icon: 'temperature-celsius', tooltip: 'Temperature Control' },\r\n { name: 'humidifier', icon: 'air-humidifier', tooltip: 'humidifier Control' }\r\n],\r\n tooltipVisible: null,\r\n tooltipStyle: {}\r\n };\r\n },\r\n computed: {\r\n containerStyles() {\r\n const pos = this.config.position || 'bottom-right';\r\n const distance = `${this.config.distance || 5}px`;\r\n \r\n let positioning = {};\r\n \r\n if (pos.includes('bottom')) {\r\n positioning.bottom = distance;\r\n } else if (pos.includes('top')) {\r\n positioning.top = distance;\r\n }\r\n \r\n if (pos.includes('right')) {\r\n positioning.right = distance;\r\n } else if (pos.includes('left')) {\r\n positioning.left = distance;\r\n }\r\n \r\n return {\r\n position: 'absolute',\r\n display: 'flex',\r\n zIndex: 1000,\r\n ...positioning\r\n };\r\n }\r\n },\r\n methods: {\r\n toggleButton(buttonName) {\r\n const newState = !this.toggleStates[buttonName];\r\n this.toggleStates[buttonName] = newState;\r\n \r\n // Send message to Node-RED\r\n this.send({\r\n payload: {\r\n [buttonName]: newState\r\n },\r\n timestamp: Date.now()\r\n });\r\n },\r\n \r\n getButtonStyle(buttonName, index) {\r\n const size = this.config.size || '35px';\r\n const border = this.config.border || 1;\r\n const colors = this.config.color || {\r\n active: '#2196F3',\r\n inactive: '#FFFFFF',\r\n hover: '#BBDEFB',\r\n border: '#E0E0E0'\r\n };\r\n \r\n const isActive = this.toggleStates[buttonName];\r\n const isFirst = index === 0;\r\n const isLast = index === this.buttons.length - 1;\r\n \r\n let backgroundColor = colors.inactive;\r\n let textColor = '#666';\r\n \r\n if (isActive) {\r\n backgroundColor = colors.active;\r\n textColor = 'white';\r\n }\r\n \r\n return {\r\n width: size,\r\n height: size,\r\n backgroundColor: backgroundColor,\r\n color: textColor,\r\n border: `${border}px solid ${colors.border}`,\r\n borderRight: isLast ? `${border}px solid ${colors.border}` : 'none',\r\n borderRadius: '0',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n cursor: 'pointer',\r\n transition: 'all 0.2s ease',\r\n userSelect: 'none',\r\n boxSizing: 'border-box'\r\n };\r\n },\r\n \r\n getIconClass(icon) {\r\n return 'material-icons';\r\n },\r\n \r\n getIconName(icon) {\r\n return icon;\r\n },\r\n \r\n getTooltipText(buttonName) {\r\n const button = this.buttons.find(b => b.name === buttonName);\r\n return button ? button.tooltip : '';\r\n },\r\n \r\n showTooltip(buttonName, event) {\r\n this.tooltipVisible = buttonName;\r\n \r\n const rect = event.target.getBoundingClientRect();\r\n this.tooltipStyle = {\r\n position: 'fixed',\r\n top: (rect.top - 35) + 'px',\r\n left: (rect.left + rect.width / 2) + 'px',\r\n transform: 'translateX(-50%)',\r\n backgroundColor: 'rgba(0, 0, 0, 0.8)',\r\n color: 'white',\r\n padding: '6px 10px',\r\n borderRadius: '4px',\r\n fontSize: '12px',\r\n whiteSpace: 'nowrap',\r\n zIndex: 10001,\r\n pointerEvents: 'none'\r\n };\r\n },\r\n \r\n hideTooltip() {\r\n this.tooltipVisible = null;\r\n }\r\n },\r\n \r\n watch: {\r\n msg: {\r\n handler(newMsg) {\r\n if (newMsg && newMsg.payload) {\r\n // Update states from incoming message\r\n Object.assign(this.toggleStates, newMsg.payload);\r\n }\r\n \r\n if (newMsg && newMsg.config) {\r\n // Update configuration from incoming message\r\n Object.assign(this.config, newMsg.config);\r\n }\r\n \r\n if (newMsg && newMsg.buttons) {\r\n // Update button definitions from incoming message\r\n this.buttons = newMsg.buttons;\r\n \r\n // Initialize states for new buttons\r\n newMsg.buttons.forEach(button => {\r\n if (!(button.name in this.toggleStates)) {\r\n this.$set(this.toggleStates, button.name, false);\r\n }\r\n });\r\n }\r\n },\r\n deep: true\r\n }\r\n }\r\n}\r\n</script>\r\n\r\n<style scoped>\r\n.toggle-widget-container {\r\n position: relative;\r\n height: 100%;\r\n width: 100%;\r\n}\r\n\r\n.toggle-button-group {\r\n display: flex;\r\n box-shadow: 0 1px 3px rgba(0,0,0,0.1);\r\n}\r\n\r\n.toggle-btn {\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.toggle-btn:hover {\r\n background-color: #BBDEFB !important;\r\n z-index: 1;\r\n}\r\n\r\n.toggle-btn.active:hover {\r\n background-color: #1976D2 !important;\r\n}\r\n\r\n.tooltip {\r\n position: fixed;\r\n background-color: rgba(0, 0, 0, 0.8);\r\n color: white;\r\n padding: 6px 10px;\r\n border-radius: 4px;\r\n font-size: 12px;\r\n white-space: nowrap;\r\n z-index: 10001;\r\n pointer-events: none;\r\n}\r\n\r\n.material-icons {\r\n font-size: 18px;\r\n line-height: 1;\r\n}\r\n</style>"},{"id":"422345191feb1813","type":"debug","z":"506727cd93754bdb","name":"Toggle Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1330,"y":1740,"wires":[]},{"id":"b93577c7977b9d29","type":"ui-group","name":"Toggle Button","page":"b55c3e3640901741","width":6,"height":1,"order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"b55c3e3640901741","type":"ui-page","name":"Test Page","ui":"b810194ea14e3502","path":"/test","icon":"home","layout":"grid","theme":"5075a7d8e4947586","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":11,"className":"","visible":true,"disabled":false},{"id":"b810194ea14e3502","type":"ui-base","name":"Dashboard 2 Examples","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-control","ui-notification"],"showPathInSidebar":false,"headerContent":"page","navigationStyle":"default","titleBarStyle":"default","showReconnectNotification":true,"notificationDisplayTime":5,"showDisconnectNotification":true,"allowInstall":true},{"id":"5075a7d8e4947586","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094ce","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"6px","groupBorderRadius":"4px","widgetGap":"12px","density":"default"}},{"id":"1582ab0dc5855460","type":"global-config","env":[],"modules":{"@flowfuse/node-red-dashboard":"1.26.0"}}]

```

---

<div class="post-metadata">

**Author:** ![rewegit](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rewegit/32/4778_2.png) [@rewegit](https://discourse.nodered.org/u/rewegit)\
**Post date:** [5 August 2025 17:05 UTC](https://discourse.nodered.org/t/dashboard-2-0-icons-in-html-template-node/98506/4 "2025-08-05T17:05:37Z")

</div>

> [@Buckskin](#):
>
> Apologies, I realised what your problem was

Thank you very much. I really messed up there. Now I'm getting somewhere.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [19 August 2025 17:06 UTC](https://discourse.nodered.org/t/dashboard-2-0-icons-in-html-template-node/98506/5 "2025-08-19T17:06:34Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
