# Downloading Files with ui-template

**URL:** <https://discourse.nodered.org/t/downloading-files-with-ui-template/88193>\
**Category:** Dashboard\
**Tags:** dashboard-2, ui-template\
**Created:** [23 May 2024 11:26 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193 "2024-05-23T11:26:25Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![sesenlik1](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sesenlik1/32/78036_2.png) [@sesenlik1](https://discourse.nodered.org/u/sesenlik1)\
**Post date:** [23 May 2024 11:26 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/1 "2024-05-23T11:26:25Z")

</div>

Hello all,

I've developed an app on Node-Red that creates some excel files and powerpoint files in the server. I want the client to be able to download the created files to client filesystem. So far I've used the below code and was able to download the testfile.txt.

```auto
<template>
    <div>
        <a href="/testfile.txt"
            Download="/testfile.txt" id="myLink">
            <v-btn type = "button"> Test Dynamic Download </v-btn>
        </a>
    </div>
</template>

```

But in the html code the path is hardcoded. Is there a way to change this path dynamically with javascript? Or is there another way to download files from server to client filesystem?

Thanks,

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [23 May 2024 12:19 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/2 "2024-05-23T12:19:26Z")

</div>

> [@sesenlik1](#):
>
> Is there a way to change this path dynamically with javascript

As with most things vue, you could probably bind them to computed variables (never tried with anchor attributes, but worth a go)

```auto
<template>
    <div>
        <a :href="fileURL" :download="filename">
            <v-btn type = "button"> Download {{ filename }}</v-btn>
        </a>
    </div>
</template>

```

---

<div class="post-metadata">

**Author:** ![sesenlik1](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sesenlik1/32/78036_2.png) [@sesenlik1](https://discourse.nodered.org/u/sesenlik1)\
**Post date:** [23 May 2024 18:37 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/3 "2024-05-23T18:37:04Z")

</div>

Hi Steve,  
Thanks for the quick reply but I could not understand how to pass the fileURL and filename with message to UI template node. Could you elaborate?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [23 May 2024 19:30 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/4 "2024-05-23T19:30:34Z")

</div>

Send the template a msg, via a change or function node (where you set the msg.fileURL and msg.filename to whatever you please).

---

<div class="post-metadata">

**Author:** ![sesenlik1](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sesenlik1/32/78036_2.png) [@sesenlik1](https://discourse.nodered.org/u/sesenlik1)\
**Post date:** [24 May 2024 09:12 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/5 "2024-05-24T09:12:22Z")

</div>

Hi Steve,  
Just tried your solution in the flow below, but I was not able to download the file. I think the problem is with passing the fileURL and filename with msg.

```auto
[
    {
        "id": "628636866bf8780c",
        "type": "ui-template",
        "z": "47bb55aaa94ef2da",
        "group": "46b7a9fdbd833857",
        "page": "",
        "ui": "",
        "name": "",
        "order": 0,
        "width": 0,
        "height": 0,
        "head": "",
        "format": "<template>\n <div>\n <a :href=\"fileURL\" :download=\"filename\">\n <v-btn type=\"button\"> Download {{ filename }}</v-btn>\n </a>\n </div>\n</template>\n\n<script>\n export default {\n data() {\n // define variables available component-wide\n // (in <template> and component functions)\n return {\n count: 0\n }\n },\n watch: {\n // watch for any changes of \"count\"\n count: function () {\n if (this.count % 5 === 0) {\n this.send({payload: 'Multiple of 5'})\n }\n }\n },\n computed: {\n // automatically compute this variable\n // whenever VueJS deems appropriate\n formattedCount: function () {\n return this.count + 'Apples'\n }\n },\n methods: {\n // expose a method to our <template> and Vue Application\n increase: function () {\n this.count++\n }\n },\n mounted() {\n // code here when the component is first loaded\n },\n unmounted() {\n // code here when the component is removed from the Dashboard\n // i.e. when the user navigates away from the page\n }\n }\n</script>\n<style>\n /* define any styles here - supports raw CSS */\n .my-class {\n color: red;\n }\n</style>",
        "storeOutMessages": true,
        "passthru": true,
        "resendOnRefresh": true,
        "templateScope": "local",
        "className": "",
        "x": 560,
        "y": 600,
        "wires": [
            []
        ]
    },
    {
        "id": "3d8accd0febacb93",
        "type": "inject",
        "z": "47bb55aaa94ef2da",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 180,
        "y": 600,
        "wires": [
            [
                "7b1105576a36fc36"
            ]
        ]
    },
    {
        "id": "7b1105576a36fc36",
        "type": "change",
        "z": "47bb55aaa94ef2da",
        "name": "",
        "rules": [
            {
                "t": "set",
                "p": "fileURL",
                "pt": "msg",
                "to": "/template_eval.xlsx",
                "tot": "str"
            },
            {
                "t": "set",
                "p": "filename",
                "pt": "msg",
                "to": "template_eval.xlsx",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 360,
        "y": 600,
        "wires": [
            [
                "628636866bf8780c"
            ]
        ]
    },
    {
        "id": "46b7a9fdbd833857",
        "type": "ui-group",
        "name": "Workshop",
        "page": "b6fd77b16bf63f30",
        "width": "12",
        "height": "1",
        "order": 1,
        "showTitle": false,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "b6fd77b16bf63f30",
        "type": "ui-page",
        "name": "Automation Workshop Panel",
        "ui": "1dd9528287925708",
        "path": "/workshop",
        "icon": "cog",
        "layout": "grid",
        "theme": "09eceb51c02d0030",
        "order": -1,
        "className": "",
        "visible": "true",
        "disabled": "false"
    },
    {
        "id": "1dd9528287925708",
        "type": "ui-base",
        "name": "Workshop Dashboard",
        "path": "/dashboard",
        "includeClientData": true,
        "acceptsClientConfig": [
            "ui-notification",
            "ui-control"
        ],
        "showPathInSidebar": false,
        "navigationStyle": "none"
    },
    {
        "id": "09eceb51c02d0030",
        "type": "ui-theme",
        "name": "Default Theme",
        "colors": {
            "surface": "#ffffff",
            "primary": "#0094ce",
            "bgPage": "#eeeeee",
            "groupBg": "#ffffff",
            "groupOutline": "#cccccc"
        },
        "sizes": {
            "pagePadding": "12px",
            "groupGap": "12px",
            "groupBorderRadius": "15px",
            "widgetGap": "12px"
        }
    }
]

```

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [24 May 2024 09:56 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/6 "2024-05-24T09:56:33Z")

</div>

You need to either address `msg.xxx` or use computed properties

direct

```auto
    <div>
        <a :href="msg.fileURL" :download="msg.filename">
            <v-btn :disabled="!msg.filename" type="button"> Download {{ msg.filename || '' }}</v-btn>
        </a>
    </div>

```

via computed

```auto
</template>
    <div>
        <a :href="fileURL" :download="filename">
            <v-btn :disabled="!filename" type="button"> Download {{ filename || '' }}</v-btn>
        </a>
    </div>
</template>

<script>
    export default {
        computed: {
            fileURL: function () {
                return this.msg?.fileURL
            },
            filename: function () {
                return this.msg?.filename
            }
        }
    }
</script>

```

---

<div class="post-metadata">

**Author:** ![sesenlik1](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sesenlik1/32/78036_2.png) [@sesenlik1](https://discourse.nodered.org/u/sesenlik1)\
**Post date:** [24 May 2024 11:16 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/7 "2024-05-24T11:16:00Z")

</div>

Thank you Steve, this solved the issue.

I know it is not in the scope of this topic but how would I trigger the download without clicking on the button, when a msg with fileURL and filename properties is received by ui-template?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [24 May 2024 11:20 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/8 "2024-05-24T11:20:24Z")

</div>

> [@sesenlik1](#):
>
> how would I trigger the download without clicking on the button, when a msg with fileURL and filename properties is received by ui-template

You can't. That would be a major security risk. Imagine vising `www.i-am-super-save.com` and they just download stuff to your computer!

---

<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:** [7 June 2024 11:20 UTC](https://discourse.nodered.org/t/downloading-files-with-ui-template/88193/9 "2024-06-07T11:20:25Z")

</div>

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