> For the complete documentation index, see [llms.txt](https://manual.bubble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual.bubble.io/help-guides/data/files.md).

# Files

Bubble provides built-in tools for uploading and storing files and images, both within the editor and in your app.

File management can be an important part of your app, depending on your needs. Some apps require publicly accessible files, like a photo-sharing platform or a marketplace displaying product images. Others need strict security to protect sensitive data, like confidential documents, personal files, or employee records.

Many apps fall somewhere in between, managing a mix of public and private files. Some files may even change their visibility based on certain conditions, for example a photo that only becomes visible if a privacy setting is marked `public = yes`.

This article covers how to upload, display, download, and delete files in Bubble, while keeping them secure through privacy rules.

{% hint style="info" %}
**A note on plugins:** Some plugins offer ways of uploading and managing files that differ from Bubble's built-in features and how they're described here. If you use a plugin to upload or manage files, we recommend getting to know the documentation for that plugin, along with any third parties it uses for file storage, conversion, or other external services.

The instructions in this article for maintaining file privacy apply specifically to Bubble's native file management features.
{% endhint %}

## How uploaded files are handled

The Bubble d atabase has two field types that support files: **file** and **image**.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FoYTmWWXfGhA7ieWpkCbC%2Fpost-fields-files.png?alt=media&amp;token=611e0b96-46f2-4e90-9b33-5a6838223de1" alt=""><figcaption></figcaption></figure>

Here's the key thing to understand about how these work: the field in the database doesn't contain the actual file, only a URL *pointing* to that file on another server. In other words, the *file* and *image* field types hold just a short string of text: the file's URL.

### What happens when a file is uploaded

When you or one of your users uploads a file using one of Bubble's built-in tools, it goes through these steps:

1. The file is uploaded to a **file storage server**.
2. That server returns a **URL** to reach the file.
3. That **URL** can be saved to the database using a workflow.

This has a few important consequences:

* The size of your file doesn't affect the size of your database, since the database only holds the URL as text. (The size still matters when the file is downloaded.)
* When you delete the contents of a file or image field, you're only deleting the URL, not the file itself.
* Files are spread across Bubble's CDN\[^1], so they download quickly.

## Managing files in the Bubble editor

### Uploading files in the editor

{% hint style="warning" %}
Files uploaded through the Bubble editor aren't protected by privacy rules\[^2]. Only upload files that are meant to be **public**.
{% endhint %}

You can upload files directly in the editor in two ways.

#### File manager

Go to the *Data* tab, in the *File manager* section, to see and search all uploaded files. To upload one, click **Upload** in the upper-right corner.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Fk6u7ErVzKQElOH4O3ePJ%2Ffiles-manager.png?alt=media&amp;token=5e376499-d4e0-43bc-a404-29c1f139fa5e" alt="The file manager showing a list of uploaded files with their size, type, and upload date, and the Upload button highlighted in the top-right corner."><figcaption><p>The file manager lists every uploaded file. Click Upload in the top-right corner to add a new one.</p></figcaption></figure>

{% hint style="info" %}
The file manager separates files uploaded in Development from those uploaded in Live. Use the link in the upper-right corner to switch between the two.
{% endhint %}

#### The database editor

When you edit a database thing that has a *file* or *image* field, you can upload a file directly to that field. Bubble uploads the file and links its URL to the thing.

### Deleting files in the editor

To delete files in the editor, go to the *Data* tab, in the *File manager* section. Select the files you want to delete using the checkboxes in the list, then click **Delete** in the upper-right corner. Keep in mind that Development and Live are separate.

{% hint style="warning" %}
If you edit a database thing and remove a file from it with the *Clear* link, this only removes the URL saved on that thing. It does not delete the file.
{% endhint %}

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FaGm7gt0EjznspA9iIL0L%2Fpost-edit.png?alt=media&amp;token=fcfad724-7413-43f7-b15e-b839fdc5d3e6" alt=""><figcaption><p>Removing an image with the <em>Clear</em> link doesn't delete the file, it only removes the URL from the database.</p></figcaption></figure>

## Managing files in a web app

### Uploading files

#### The upload elements

To let users upload files, you can choose between two Bubble-native elements: the **file uploader** and the **image uploader**. Both upload files and store their URLs in the database, but each has a few differences.

<table><thead><tr><th width="97.921875"></th><th>Image uploader</th><th>File uploader</th></tr></thead><tbody><tr><td>Accepts</td><td>Image formats</td><td>All file types</td></tr><tr><td>Preview</td><td>Shows a preview of the image</td><td>Shows the filename, which users can click to download</td></tr><tr><td>Sizing</td><td>Can resize images larger than 800 x 600 pixels to those dimensions, if you check the box</td><td>Lets you set a maximum file size in megabytes</td></tr></tbody></table>

When empty, both elements open the standard operating system file selector.

{% hint style="warning" %}
As soon as a user uploads a file, it's sent to the file storage server and has a live URL that anyone with the link can view, even before you've saved that URL to the database. To keep files private, see using [privacy rules with files](#uploading-private-files-1) below.
{% endhint %}

#### Saving the URL in the database

Once a file is uploaded through one of the elements, the element's value returns the file's URL. You then use a workflow to save that URL to a field on the relevant data type.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2Ff4rJFaBakyHtWbqGC1wK%2Fupload-cover-image.png?alt=media&amp;token=53297121-278e-4e7a-b9ea-73807b8088d3" alt="A workflow triggered by a cover image upload, with a Make changes to Post action that sets the post&#x27;s cover_image field to the picture uploader&#x27;s value."><figcaption><p>After the file uploads, a <a href="/core-resources/bubble-workflows/bubble-actions/database-actions.md#make-changes-to-thing">Make changes to a thing</a> action saves its URL to a field on the record. Here, the uploader's value is saved to the post's cover_image field.</p></figcaption></figure>

### Uploading private files

Private files are linked to a specific database record and inherit the privacy rules of that data type. For example, if a user uploads a cover image to their blog post, the file is protected according to the privacy rules set on the *Post* data type.

Keeping a file private takes a few settings, in two places: the uploader element and the data type's privacy rules.

{% stepper %}
{% step %}

#### Make the file private

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FgpOVLM4CsVbVFaekApEs%2Fmake-uploaded-file-private%202.png?alt=media&amp;token=3472a299-89bc-4d8e-bb1e-3ede6694329f" alt="The picture uploader&#x27;s properties with the Make private toggle turned on and Attach this file to set to Current page&#x27;s Post."><figcaption><p>Turn on <em>Make private</em> in the picture uploader's properties.</p></figcaption></figure>

On the uploader element, check the box *Make this file private*.<br>
{% endstep %}

{% step %}

#### Attach it to a thing

A dynamic field appears where you specify which database thing to attach the file to. In this example, we've set it to the `Current page's Post`.

Attaching the file to a thing is what ties its privacy to that record. Once a file is attached, it inherits the privacy rules of that thing's data type. If you attach a private file to a post, the post's privacy rules now govern the file too: the *View attached files* permission on the *Post* data type decides who's allowed to see it. Without attaching the file to a thing, there's no record for it to inherit rules from, which is why this step is what makes a private upload actually private.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FN9BISWCqMYZBEP24ZAfR%2Fmake-uploaded-file-private%203.png?alt=media&amp;token=bcb07d0a-9c6b-4cd0-8938-9b6ccd8a628d" alt="The picture uploader&#x27;s properties with the Attach this file to field highlighted, set to Current page&#x27;s Post."><figcaption><p>In the Attach this file to field, choose the thing whose privacy rules should govern the file. Here it's set to Current page's Post.</p></figcaption></figure>
{% endstep %}

{% step %}

#### Check the privacy rules

Marking the file private on the element isn't enough on its own. It binds the file to the thing, but the thing's privacy rules are what actually control access. Go to the *Post* data type's privacy rules and make sure *View attached files* is unchecked for anyone who shouldn't see the file. This is the setting that keeps the file itself out of reach, even from someone who somehow gets hold of its URL.

<figure><img src="https://34394582-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5sbzwG7CljeZdkntrL%2Fuploads%2FkjIVJ9h1OMJDQY8nFhgB%2Fprivacy-rule-file.png?alt=media&amp;token=80075761-be0d-4521-900e-ac23ce0f78b7" alt="Privacy rules on the Post data type. The Shared with rule has View files attached to this checked, while the Everyone else rule has it unchecked."><figcaption><p>The View files attached to this permission is what controls access to the file itself. Here it's granted to shared users but withheld from everyone else.</p></figcaption></figure>
{% endstep %}
{% endstepper %}

## Deleting uploaded files

Removing the contents of a file or image field only clears the URL stored on the thing. The file itself stays on the storage server, still accessible to anyone with the link. To delete the file as well, you need to run two actions, and the order matters.

{% stepper %}
{% step %}

#### Delete the file

Use the [**Delete an uploaded file**](/core-resources/actions/data-things.md#delete-an-uploaded-file) action first. This action needs the file's URL to know which file to remove, so it has to run while the URL is still saved on the thing. If you cleared the field first, the action would have nothing to point to.
{% endstep %}

{% step %}

#### Clear the field

Use a [**Make changes to a thing**](/core-resources/bubble-workflows/bubble-actions/database-actions.md#make-changes-to-thing) action to clear the field that stored the URL. This makes sure you're not left holding a URL that points to a file that no longer exists.
{% endstep %}
{% endstepper %}

## FAQ: Files

<details>

<summary>What's the difference between a file field and an image field?</summary>

Both store the URL of an uploaded file, not the file itself. The *image* field is meant for image formats and pairs with the image uploader, which can show a preview and resize large images. The *file* field accepts any file type and pairs with the file uploader, which shows the filename and lets users download it.

</details>

<details>

<summary>If I clear a file field, is the file deleted?</summary>

No. Clearing a file or image field only removes the URL saved on that thing. The file itself stays on the storage server and remains accessible to anyone with the link. To remove the file too, you need to delete it separately.

</details>

<details>

<summary>How do I permanently delete a file?</summary>

Follow the steps described [here](#deleting-uploaded-files).

</details>

<details>

<summary>Why does the delete action have to come before clearing the field?</summary>

The **Delete an uploaded file** action identifies the file by its URL. If you clear the field first, the URL is gone and the action has nothing to point to. Deleting the file first, then clearing the field, keeps the two in sync.

</details>

<details>

<summary>Are files I upload through the editor private?</summary>

**No**. Files uploaded through the file manager or the database editor aren't protected by privacy rules. Only upload files there that are meant to be public.

</details>

<details>

<summary>How do I make a user-uploaded file private?</summary>

Follow the steps described [here](#make-the-file-private).

</details>

<details>

<summary>Is turning on "Make private" enough to secure a file?</summary>

No. That setting attaches the file to a thing, but the thing's privacy rules are what actually control access. Without setting *View files attached to this* on the data type, the file isn't secured.

</details>

<details>

<summary>What's the difference between hiding the URL field and "View files attached to this"?</summary>

Hiding the field (by unchecking *View*) stops a user from seeing the URL, but if they obtained the URL another way, they could still open the file. *View files attached to this* protects the file itself, so even someone with the URL gets an error. Only the second setting makes a file truly secure. The first only obscures it.

</details>

<details>

<summary>Should I use the image uploader or the file uploader?</summary>

Use the image uploader for images, since it previews the image and can resize ones larger than 800 x 600 pixels. Use the file uploader for any other file type, since it accepts all formats, shows the filename for download, and lets you set a maximum file size.

</details>

<details>

<summary>Can a file be accessed before I save its URL to the database?</summary>

Yes. As soon as a user uploads a file, it's sent to the storage server and has a live URL that anyone with the link can view, even before you've saved that URL to the database. If the file needs to be private, make sure it's set up as a private upload.

</details>

## Other ways to learn

<details>

<summary>Video lessons</summary>

* [How to use the file uploader element](https://youtu.be/2wQo0Nve4Zs)
* [How to delete files attached to things](https://youtu.be/-z6b2UH_JAw)

</details>

<details>

<summary>Related articles</summary>

* [The file and image uploader elements](/help-guides/design/elements/web-app/input-forms/file-uploads.md)

</details>
