Skip to main content
RapidDev - Software Development Agency
bubble-tutorial

How to build file downloads in Bubble

Bubble stores uploaded files as URLs, so downloading requires either opening the URL in a new tab or using JavaScript to force a browser download. This tutorial covers both approaches: the simple open-in-new-tab method and the forced download method using the Toolbox plugin, plus how to generate temporary download links.

What you'll learn

  • How to open files in a new browser tab for viewing
  • How to force a file download instead of opening in the browser
  • How to create download buttons in Repeating Groups
  • How to track download counts per file
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read10-15 minAll Bubble plansMarch 2026RapidDev Engineering Team
TL;DR

Bubble stores uploaded files as URLs, so downloading requires either opening the URL in a new tab or using JavaScript to force a browser download. This tutorial covers both approaches: the simple open-in-new-tab method and the forced download method using the Toolbox plugin, plus how to generate temporary download links.

Overview: Handling File Downloads in Bubble

When users upload files to your Bubble app, those files are stored as URLs on Bubble's servers. Getting users to download those files requires a workflow that either opens the URL in a new tab or triggers a forced download. This tutorial covers both methods so you can provide the right download experience for your app.

Prerequisites

  • A Bubble app with files already stored in the database
  • Basic understanding of Bubble workflows
  • The Toolbox plugin installed (optional, for forced downloads)

Step-by-step guide

1

Add a download button that opens the file in a new tab

This is the simplest approach. On your page, add a Button element labeled Download. In its workflow, add the action Navigation → Open an external website. For the URL, use the dynamic expression that points to your file field — for example, Current cell's Document's attachment. Check the Open in a new tab option. Images and PDFs will typically display in the browser, while other file types will trigger a download automatically.

Pro tip: Append ?dl= to the end of the file URL to hint to some browsers that the file should be downloaded rather than displayed.

Expected result: Clicking the button opens the file in a new browser tab. PDFs and images display inline; other files download automatically.

2

Force a download using the Toolbox plugin's Run JavaScript action

Install the Toolbox plugin from the Plugins tab if you have not already. In your download button's workflow, add the action Plugins → Run JavaScript. Enter this code: var link = document.createElement('a'); link.href = 'DYNAMIC_URL'; link.download = 'DYNAMIC_FILENAME'; document.body.appendChild(link); link.click(); document.body.removeChild(link); Replace DYNAMIC_URL with the file's URL and DYNAMIC_FILENAME with the desired filename. Use Bubble's dynamic data insertion to populate these values.

Run JavaScript action
1var link = document.createElement('a');
2link.href = 'https://your-app.bubbleapps.io/file/abc123';
3link.download = 'document.pdf';
4document.body.appendChild(link);
5link.click();
6document.body.removeChild(link);

Pro tip: The forced download approach may not work for cross-origin files in all browsers. Test across Chrome, Safari, and Firefox.

Expected result: Clicking the button triggers an immediate file download to the user's device instead of opening in the browser.

3

Create download links inside a Repeating Group

If you display files in a Repeating Group, add a Link element inside each cell. Set the Link destination to External URL and use Current cell's Document's attachment as the dynamic URL. Set the link text to something like the file title or Download File. Enable Open in a new tab. This creates a clickable download link for every file in the list without needing a separate workflow.

Expected result: Each row in the Repeating Group has a clickable link that downloads or opens the associated file.

4

Track download counts for each file

Add a number field called download_count to your file Data Type. In the download button's workflow, add an action before or after the download: Make Changes to Current cell's Document, setting download_count to Current cell's Document's download_count + 1. Display this count in a Text element inside the Repeating Group cell to show how many times each file has been downloaded.

Expected result: Every download increments a counter, and users can see how many times each file has been downloaded.

Complete working example

Workflow summary
1FILE DOWNLOAD WORKFLOW SUMMARY
2===============================
3
4METHOD 1: Open in New Tab
5 Button: DownloadButton
6 Workflow: When DownloadButton is clicked
7 Action: Open an external website
8 URL: Current cell's Document's attachment
9 Open in new tab: yes
10
11METHOD 2: Forced Download (Toolbox plugin)
12 Button: DownloadButton
13 Workflow: When DownloadButton is clicked
14 Action 1: Run JavaScript
15 Script:
16 var link = document.createElement('a');
17 link.href = '[Current cell's Document's attachment]';
18 link.download = '[Current cell's Document's title]';
19 document.body.appendChild(link);
20 link.click();
21 document.body.removeChild(link);
22 Action 2: Make Changes to Current cell's Document
23 download_count = download_count + 1
24
25METHOD 3: Link Element in Repeating Group
26 Link element inside RG cell:
27 Destination: External URL
28 URL: Current cell's Document's attachment
29 Open in new tab: yes
30 Text: Current cell's Document's title
31
32DATA STRUCTURE:
33 Document Data Type:
34 - title (text)
35 - attachment (file)
36 - download_count (number, default: 0)
37 - uploaded_by (User)

Common mistakes when building file downloads in Bubble

Why it's a problem: Expecting all files to auto-download when opened in a new tab

How to avoid: Use the Toolbox Run JavaScript forced download method for file types that browsers typically display inline

Why it's a problem: Not handling missing or deleted files

How to avoid: Add a condition to hide the download button when the file field is empty, and periodically clean up orphaned file references

Why it's a problem: Making file URLs publicly accessible without access controls

How to avoid: Set Privacy Rules on the Data Type containing the file field to restrict which users can view the file URL

Best practices

  • Use the Open in new tab method for simplicity unless you specifically need forced downloads
  • Add Privacy Rules to control who can access file URLs in your database
  • Track download counts if analytics are important for your use case
  • Show the file type and size next to the download button for better user experience
  • Test downloads across multiple browsers since download behavior varies
  • Use descriptive filenames in the forced download method so users know what they saved

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I have a Bubble.io app with files stored in the database. I need to add download buttons that work for all file types including PDFs and images. How do I force a browser download instead of opening the file in a new tab?

Bubble Prompt

Add download functionality to my file list. I have a Repeating Group showing documents. Each row needs a download button that forces the browser to download the file instead of opening it.

Frequently asked questions

Why does my PDF open in the browser instead of downloading?

Most browsers display PDFs inline by default. Use the Toolbox plugin's Run JavaScript action with the link.download attribute to force a download, or append ?dl=1 to the URL.

Can I generate a temporary or expiring download link?

Bubble does not natively support expiring URLs. You can build a workaround by creating a backend workflow that checks a token and timestamp before redirecting to the file URL.

Are file URLs permanent?

Yes, as long as the file exists in your Bubble app. File URLs remain valid unless you manually delete the file from the File Manager or delete the app.

How do I handle large file downloads without timeouts?

Bubble serves files directly from its CDN, so large files should download without timeout issues. If users report slow downloads, the bottleneck is likely their internet connection, not Bubble.

Can I restrict downloads to logged-in users only?

Yes. Set Privacy Rules on the Data Type so the file field is only visible to logged-in users. Without access to the URL, they cannot download the file. For enterprise-level access control, RapidDev can help design secure file access systems.

Can I let users preview a file before downloading?

For images, use an Image element with the file URL as the source. For PDFs, use an HTML element with an iframe pointing to the file URL. Other file types generally cannot be previewed in the browser.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.