Isolating Vue/SVG Components in ui-template

Hi there!

I'm using the ui-template node from Dashboard 2.0 to create a dynamic operational screen. I've been combining Vue.js and SVG to make the elements interactive.

My project is getting larger, and the single ui-template node is becoming difficult to manage, with a lot of SVG elements and functions all in one place.

I'd like to know if it's possible to break down these components. For instance, can I separate just the SVG code from the section and put it into a different file or node, and then reference it from the ui-template?

Any guidance on how to better structure this would be a huge help!

Thanks in advance!

You can serve content using http-in~http-response nodes (i.e. create an endpoint) and use regular web imports in the template.

Thank you for pointing this alternative. I never tried something similar in the past, thus I'm not sure if I understood it right.

Can you give me some examples?

I asked about something similar, someone suggested teleports but I haven't tested them yet

I think it works

[
    {
        "id": "d6a3e0b6ab0e388e",
        "type": "ui-template",
        "z": "19cb94d5b096ef08",
        "group": "cd0dac1475062196",
        "page": "",
        "ui": "",
        "name": "main",
        "order": 1,
        "width": 0,
        "height": 0,
        "head": "",
        "format": "<template>\n     main\n  <div id=\"aaqu-target\"></div>\n</template>",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 230,
        "y": 600,
        "wires": [
            []
        ]
    },
    {
        "id": "bbe97f8f97bd2b88",
        "type": "ui-template",
        "z": "19cb94d5b096ef08",
        "group": "cd0dac1475062196",
        "page": "",
        "ui": "",
        "name": "second",
        "order": 2,
        "width": 0,
        "height": 0,
        "head": "",
        "format": "<template>\n\n  <Teleport v-if=\"mounted\" to=\"#aaqu-target\">\n      second\n      <svg height=\"100\" width=\"100\" xmlns=\"http://www.w3.org/2000/svg\">\n        <circle r=\"45\" cx=\"50\" cy=\"50\" stroke=\"green\" stroke-width=\"3\" fill=\"red\" />\n      </svg>\n  </Teleport>\n\n</template>\n\n<script>\nexport default {\n  data(){ \n    return { mounted: false }\n  },\n  mounted(){ this.mounted = true },\n}\n</script>\n",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 240,
        "y": 660,
        "wires": [
            []
        ]
    },
    {
        "id": "35729a1f8963daed",
        "type": "ui-template",
        "z": "19cb94d5b096ef08",
        "group": "cd0dac1475062196",
        "page": "",
        "ui": "",
        "name": "second",
        "order": 3,
        "width": 0,
        "height": 0,
        "head": "",
        "format": "<template>\n\n  <Teleport v-if=\"mounted\" to=\"#aaqu-target\">\n      third\n      <svg height=\"100\" width=\"100\" xmlns=\"http://www.w3.org/2000/svg\">\n        <circle r=\"45\" cx=\"50\" cy=\"50\" stroke=\"green\" stroke-width=\"3\" fill=\"purple\" />\n      </svg>\n  </Teleport>\n\n</template>\n\n<script>\nexport default {\n  data(){ \n    return { mounted: false }\n  },\n  mounted(){ this.mounted = true },\n}\n</script>\n",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 240,
        "y": 700,
        "wires": [
            []
        ]
    },
    {
        "id": "cd0dac1475062196",
        "type": "ui-group",
        "name": "Group 1",
        "page": "e188ea992f7b5998",
        "width": 6,
        "height": 1,
        "order": 1,
        "showTitle": true,
        "className": "",
        "visible": true,
        "disabled": false,
        "groupType": "default"
    },
    {
        "id": "e188ea992f7b5998",
        "type": "ui-page",
        "name": "Page 1",
        "ui": "98d9c169110a1e36",
        "path": "/page1",
        "icon": "home",
        "layout": "grid",
        "theme": "c757d5c250b7d202",
        "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": 1,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "98d9c169110a1e36",
        "type": "ui-base",
        "name": "My Dashboard",
        "path": "/dashboard",
        "appIcon": "",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "headerContent": "page",
        "navigationStyle": "default",
        "titleBarStyle": "default",
        "showReconnectNotification": true,
        "notificationDisplayTime": 1,
        "showDisconnectNotification": true,
        "allowInstall": true
    },
    {
        "id": "c757d5c250b7d202",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094CE",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "density": "default",
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "4px",
            "widgetGap": "12px"
        }
    },
    {
        "id": "2d464c2dbefc2ced",
        "type": "global-config",
        "env": [],
        "modules": {
            "@flowfuse/node-red-dashboard": "1.27.0"
        }
    }
]