0๐
โ
use a route that captures the "tracking-source" parameter and performs the necessary tracking action, and then serves the file using the sendFile method from the express library.
Here is an example of how to set up a route in a Vue project using the vue-router library:
import Vue from 'vue'
import Router from 'vue-router'
import path from 'path'
import express from 'express'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/some/path/:fileName/:trackingSource',
name: 'download-file',
component: {
beforeRouteEnter (to, from, next) {
const { params } = to
// Perform tracking action using the trackingSource parameter
// ...
// Serve the file
const filePath = path.join(__dirname, 'path/to/files', `${params.fileName}.txt`)
express.sendFile(filePath, (err) => {
if (err) next(err)
})
}
}
}
]
})
here the route captures the "fileName" nd "trackingSource" parameters from the URL, and uses the beforeRouteEnter navigation guard to perform the tracking action and serve the file.
without express you can do something like this
<template>
<div>
<a ref="downloadLink" :href="fileUrl" download>Download</a>
<button @click="downloadFile">Download</button>
</div>
</template>
<script>
export default {
data() {
return {
fileUrl: ''
}
},
methods: {
async downloadFile() {
const { params } = this.$route
const fileName = `${params.fileName}.txt`
const filePath = `/path/to/files/${fileName}`
const response = await fetch(filePath)
if (!response.ok) {
throw new Error(`Failed to fetch file: ${response.status}`)
}
const blob = await response.blob()
this.fileUrl = window.URL.createObjectURL(blob)
this.$refs.downloadLink.click()
}
}
}
</script>
0๐
Since I also store my files in the public/files directory of the vue project, I opted to not fetch it.
{
path: '/files/:fileName/:source',
redirect: to => {
const fileName = to.params.fileName
logEvent(analytics, fileName, {source: to.params.source});
const a = document.createElement('a');
document.body.appendChild(a);
a.href = `/files/${fileName}`;
a.download = fileName;
a.click();
setTimeout(() => {
window.URL.revokeObjectURL(a.href);
document.body.removeChild(a);
}, 0)
return {path: '/' }
}
}
Source:stackexchange.com