# How to build file downloads in Bubble

- Tool: Bubble
- Difficulty: Beginner
- Time required: 10-15 min
- Compatibility: All Bubble plans
- Last updated: March 2026

## 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.

## Before you start

- 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.

```
var link = document.createElement('a');
link.href = 'https://your-app.bubbleapps.io/file/abc123';
link.download = 'document.pdf';
document.body.appendChild(link);
link.click();
document.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 code example

File: `Workflow summary`

```text
FILE DOWNLOAD WORKFLOW SUMMARY
===============================

METHOD 1: Open in New Tab
  Button: DownloadButton
  Workflow: When DownloadButton is clicked
    Action: Open an external website
      → URL: Current cell's Document's attachment
      → Open in new tab: yes

METHOD 2: Forced Download (Toolbox plugin)
  Button: DownloadButton
  Workflow: When DownloadButton is clicked
    Action 1: Run JavaScript
      → Script: 
         var link = document.createElement('a');
         link.href = '[Current cell's Document's attachment]';
         link.download = '[Current cell's Document's title]';
         document.body.appendChild(link);
         link.click();
         document.body.removeChild(link);
    Action 2: Make Changes to Current cell's Document
      → download_count = download_count + 1

METHOD 3: Link Element in Repeating Group
  Link element inside RG cell:
    → Destination: External URL
    → URL: Current cell's Document's attachment
    → Open in new tab: yes
    → Text: Current cell's Document's title

DATA STRUCTURE:
  Document Data Type:
    - title (text)
    - attachment (file)
    - download_count (number, default: 0)
    - uploaded_by (User)
```

## Common mistakes

- **Expecting all files to auto-download when opened in a new tab** — Browsers display certain file types (images, PDFs, videos) inline instead of downloading them Fix: Use the Toolbox Run JavaScript forced download method for file types that browsers typically display inline
- **Not handling missing or deleted files** — If a file was deleted from the File Manager but the URL is still in the database, the download link will lead to a 404 error Fix: Add a condition to hide the download button when the file field is empty, and periodically clean up orphaned file references
- **Making file URLs publicly accessible without access controls** — Anyone with the file URL can download the file, even without being logged in to your app Fix: 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

## 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.

---

Source: https://www.rapidevelopers.com/bubble-tutorial/handle-file-download-in-bubble
© RapidDev — https://www.rapidevelopers.com/bubble-tutorial/handle-file-download-in-bubble
