Make file available upon user button click.

ZachJ
ZachJ Member Posts: 8

Using Node.js/Next.js. My API grabs some data, generates an excel file and then uploads the file to Cloudinary. When the user clicks a button I need the excel file to be available to them for download. It appears the excel file link is saved in result.secure_url. I'm stuck on how to get this link into a clickable button. I think I need to setup a route or a GET request but unsure how to go about this. Any guidance or can point me to any documentation that may help?

Answers

  • DannyFromCloudinary
    DannyFromCloudinary Member, Cloudinary Staff Posts: 142

    Hey @ZachJ .

    Thanks for getting in touch.

    You shouldn't need to create any additional routes or configs in your application. Instead, there are a couple of options available to you.

    If you have a CNAME with us, you would just be able to capture the secure_url and serve it to the customer as an a tag with the download attribute.

    For instance: <a href="https://assets.yoursite.com/raw/upload/your_file.xlsx" download>Download Excel File</a> .

    The reason a CNAME is required is because the download attribute only works for same-origin URLs. For more info on the download attribute, this article from MDN gives a good deep-dive: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#download


    Alternatively, if you don't have a CNAME, or you don't particularly like this approach, we do have a flag called fl_attachment, that triggers the browser to download the asset in question. You would just add it as a transformation and then use that in your a tag, such as: <a href="https://res.cloudinary.com/your-cloud/raw/upload/fl_attachment/your_file.xlsx" target="_blank">Download Excel File</a> .

    The docs for fl_attachment can be found here: https://cloudinary.com/documentation/transformation_reference#fl_attachment

    I hope this helps. Please let me know if you have any further questions.


    All the best,

    -Danny

  • ZachJ
    ZachJ Member Posts: 8

    Turns out I needed to use props to communicate the url over to the client side page after it's generated. But I still have the issue of having to hardcode the exact url in instead of just being able to use a dynamic variable of result.secure_url that it appears cloudinary stores the url in? console.log(result.secure_url) pops out the url in the terminal but when I try to use the variable result.secure_url and pass it through with props I get an undefined error. I tried storing result.secure_url in my own variable even. I don't think anything above is a solution to that right?

  • DannyFromCloudinary
    DannyFromCloudinary Member, Cloudinary Staff Posts: 142

    Hi Zach.

    I'm not a Next user myself, but let me ask around internally and see if any of my colleagues could chime in here.

    Thanks,

    -Danny

  • ZachJ
    ZachJ Member Posts: 8

    It's ok thanks for your assistance, I'm all set looks like I got it to recognize the Cloudinary result.secure_url variable by setting up a callback, or a promise works too. Next.js has not been a blast to use so far.

  • Cloudinary Team
    Cloudinary Team Administrator, Cloudinary Staff Posts: 160 admin

    Hi Zach,

    Thanks for the update. I'm glad you got it working 😊

    Kind regards,

    Tia

    Helpful Links For You
    💬 Share questions, connect with other users in our Cloudinary Community forums and Discord server!
    🧑‍🎓 Join our Cloudinary Academy for free courses, workshops and other educational resources.
    📄 Read our documentation for in-depth details on Cloudinary product features and capabilities
    📰 Check out the Cloudinary blog for the latest company news and insights

  • colbyfayock
    colbyfayock Member, Cloudinary Staff Posts: 8

    hey @ZachJ sorry you're not having a great experience in Next.js. id love to hear more about the solution you came to and how i can either help smooth things out or at least set other people up for success. do you perhaps have some sample code or is the project open source?

    if not, would you be interested in sending me a message through these forums with some of that? you can do so by clicking my name and clicking Message

    wanted to also give you a heads up that there's a Next.js SDK available, though its currently more focused on front end implementation (image component, widgets): https://next.cloudinary.dev/

  • ZachJ
    ZachJ Member Posts: 8
    edited February 23

    I realized the next day it wouldn't actually work because after my api generated the excel file it's saved on my drive and then I was uploading to cloudinary from my drive. Running the api on a browser non locally it would get stuck before it ever get's uploaded to cloudinary. I'm wondering if I can create a blob using Filesaver.js. and upload to cloudinary by cloudinary.uploader.upload(blob info in here) but I'm not sure if that's possible. The blob doesn't supply an actual url for me to put in there.

    Read something on Stackoverflow that I don't really understand yet, think it's to do with images though and not xlsx.... "If you're able to access the blob data (not just the blob URL), it can be converted to a data URI which will be accepted by the file parameter to Cloudinary's upload method."

  • ZachJ
    ZachJ Member Posts: 8

    Nevermind, was able to get it to work.

    // Wrote the excel workbook to a buffer

    workbook.xlsx.writeBuffer().then((buffer) => {

    // Convert the buffer to a readable stream

    const stream = streamifier.createReadStream(buffer);

    // Upload the stream to Cloudinary

    const uploadStream = cloudinary.uploader.upload_stream(...rest of your specific code here