# Filestack

- Tool: Bubble
- Difficulty: Beginner
- Time required: 1–2 hours
- Last updated: July 2026

## TL;DR

Connect Bubble to Filestack using a community plugin from the Plugin Marketplace — the plugin wraps the Filestack Picker and exposes it as a Bubble element with upload events. Filestack is not raw object storage: it is an upload pipeline with a hosted drag-and-drop widget, 20+ cloud source integrations, and on-the-fly image transformation URLs. No presign proxy needed for basic uploads.

## Filestack is an upload pipeline — not raw storage

Every other tool in this category (Amazon S3, Wasabi, Backblaze B2, Dropbox, Box) is raw object storage: your app is responsible for building the upload UI, handling file selection, generating presigned URLs, and managing the upload flow. Filestack is fundamentally different.

Filestack provides a hosted, configurable Picker widget that handles the entire upload interaction: drag-and-drop, file system browsing, URL imports, and 20+ cloud source integrations (Google Drive, Dropbox, OneDrive, Instagram, Facebook) — all through a modal that appears in your Bubble app when triggered. The user selects files from any source; Filestack handles the upload to its CDN; your Bubble app receives a file handle (a short identifier) in the success event.

After upload, Filestack's real advantage becomes visible: transformation URLs. To display a 400px wide WebP version of an uploaded image, you construct `https://cdn.filestackcontent.com/resize=width:400/output=format:webp/{fileHandle}` as the Image element's URL. No server code, no additional upload, no storage cost for the variant — the transformation happens on Filestack's CDN on demand.

For Bubble: a Plugin Marketplace plugin wraps the Filestack SDK and exposes the Picker as a Bubble element. The free tier supports 500 uploads/month, 100 image transformations/month, and 500 MB storage — sufficient for prototyping. Growth plans start at approximately $49/month (verify at filestack.com/pricing).

The key security distinction: the Filestack API key (prefixed with your app key) is intentionally semi-public — it appears in the Picker's embed code and is visible to users who inspect page source. This is by design. The API Secret, used only for security policies, is fully private and must never appear in client-side code.

## Before you start

- A Filestack account — sign up at filestack.com. The free tier supports up to 500 uploads/month and 100 transformations/month
- Your Filestack API key from the Filestack dashboard (semi-public, used in plugin settings)
- A Bubble app (any plan for basic plugin uploads — Backend Workflows for security policy signing require a paid Bubble plan)
- The Bubble Plugin Marketplace accessible in your app (Plugins tab → Add plugins)

## Step-by-step guide

### 1. Get your Filestack API key from the dashboard

Sign in at app.filestack.com (or create a free account if you haven't). In the Filestack dashboard, go to the main Overview or Settings section. Your API key is displayed prominently — it looks like `AjTus5EwuTdeGy3wGgkwpz` (a random alphanumeric string). Copy it.

Also note whether Filestack Security is enabled on your account (Security tab in the Filestack dashboard). If Security is disabled (the default for new accounts), you only need the API key for the integration. If Security is enabled, you will also need the API Secret — a separate credential that must NEVER be placed in client-side code or in Bubble's page elements. For this tutorial, we assume Security is disabled (standard for most Bubble use cases).

Understand the API key's role: unlike an S3 access key or a B2 application key, the Filestack API key is designed to appear in frontend code. It authorizes the Picker to accept uploads to your Filestack account. The rate limiting and access control happen at Filestack's infrastructure level. Treat it carefully (store in plugin settings, not hardcoded in text), but it is not the same category of secret as a private key or database password.

```
{
  "filestack_dashboard": "https://app.filestack.com",
  "api_key_location": "Dashboard → API Keys or Overview panel",
  "api_key_format": "Example: AjTus5EwuTdeGy3wGgkwpz",
  "note": "This API key is semi-public — it appears in the Picker embed code. Store in plugin settings, not in Bubble text fields. The API Secret (Security tab) is fully private — required only if you enable Filestack Security policies."
}
```

**Expected result:** You have your Filestack API key copied. You know whether Filestack Security is enabled on your account. Ready to install the Bubble plugin.

### 2. Find and install a Filestack plugin in Bubble's Plugin Marketplace

In your Bubble app editor, click the Plugins tab in the left sidebar. Click 'Add plugins'. In the search bar, type 'Filestack'. You will see community-created plugins that wrap the Filestack SDK.

Before installing, review each plugin's listing carefully:
- Check the 'Last updated' date — a plugin not updated in 12+ months may be incompatible with recent Filestack API changes.
- Read the reviews for mentions of the Picker working correctly and the upload success event firing reliably.
- Check whether the plugin exposes the fields you need from the upload result: at minimum, `fileHandle` (the short identifier) and the CDN URL.

Install the plugin that best meets these criteria. After installation, the plugin will appear in your Plugins list. Open it and enter your Filestack API key in the designated field. Look for a field labeled 'API Key' or 'Filestack API Key' — this is where the API key belongs, stored in plugin settings rather than in a page element or workflow value.

If no suitable plugin is available or if the available plugins have been unmaintained for too long, skip to Step 5 for the API Connector fallback approach. The API Connector can handle Filestack's CDN metadata and transformation calls even without a plugin.

```
{
  "plugin_search_term": "Filestack",
  "evaluation_checklist": [
    "Last updated within 12 months",
    "Reviews mention Picker opening correctly",
    "Upload success event fires reliably",
    "Exposes file handle and CDN URL in results",
    "Compatible with current Bubble version"
  ],
  "plugin_settings": {
    "api_key_field": "Your Filestack API key (e.g., AjTus5EwuTdeGy3wGgkwpz)",
    "note": "Do not put the API key in page text elements or workflow input values — plugin settings is the correct location"
  }
}
```

**Expected result:** A Filestack plugin is installed in your Bubble app and configured with your API key in the plugin settings panel.

### 3. Add the Filestack Picker element to your page

With the plugin installed, open the page where you want the file upload functionality. In Bubble's element panel (click the Add icon in the left sidebar), look for a new visual element added by the Filestack plugin — typically named 'Filestack Picker', 'Filestack Uploader', or similar.

Drag the element onto the canvas. Unlike a standard Bubble file uploader input, the Filestack Picker is typically an invisible trigger element that opens a modal when activated. Size and position it according to the plugin's documentation — often you place it anywhere on the page and trigger it via a button workflow.

In the element's property panel, configure the Picker options:
- **Accepted file types**: Set the list of MIME types or extensions your app accepts (e.g., `image/*`, `.pdf`, `.docx`). Leave blank to accept all file types.
- **Upload sources**: Enable or disable cloud sources (Google Drive, Dropbox, etc.). Most plugins let you configure which sources appear in the Picker.
- **Max files**: Set how many files a user can select in one Picker session.
- **Max file size**: Set a size limit in bytes to reject oversized uploads before they reach Filestack.

These options configure the hosted Picker that Filestack serves — your Bubble app's styling does not apply inside the Picker modal (it's an iframe from Filestack's CDN).

```
{
  "picker_element_type": "Filestack Picker (from installed plugin)",
  "configuration_options": {
    "accepted_types": "image/*, application/pdf",
    "max_files": 5,
    "max_file_size_bytes": 10485760,
    "sources": ["local_file_system", "googledrive", "dropbox", "onedrive", "url"]
  },
  "element_placement": "Can be 0×0 invisible element — trigger via workflow button click"
}
```

**Expected result:** The Filestack Picker element is on the page and configured with your accepted file types and upload sources. The element is ready to be triggered.

### 4. Wire the upload success event to save the file handle

The Filestack Picker fires an event when an upload completes. In Bubble, you handle this in the Workflow editor. Click on the Filestack Picker element and open the Workflow tab. You should see an event triggered by the plugin — typically named 'When Filestack upload completes', 'On upload success', or similar.

In this workflow, add the following steps:

Step 1: 'Make changes to a Thing' (or 'Create a new Thing' if you're creating a record). Set the relevant fields:
- A 'file_handle' text field: bind to the Picker event's result — look for a field named `handle`, `fileHandle`, or similar in the event data. This is a short unique identifier like `1P89wkysTkePPiSzNHcI`.
- A 'file_url' text field: bind to the CDN URL returned by the event (often `https://cdn.filestackcontent.com/{handle}`).
- A 'file_name' text field: bind to the original filename from the event data.
- A 'file_type' text field: bind to the MIME type from the event data.

Step 2 (optional): Show a success alert or navigate the user to see their uploaded file.

Critical: save the `fileHandle` (short ID), NOT just the CDN URL. The file handle is the stable identifier — you construct transformation variants from it dynamically. The plain CDN URL serves the original file; transformation URLs are derived from the handle at display time.

Also add error handling: look for an 'On upload error' event in the same Picker element. Add a workflow that shows an error message to the user if the upload fails.

```
// Bubble workflow structure — Filestack upload success
// Event: When [Filestack Picker Element] upload completes

// Step 1: Make changes to CurrentUser's File record (or Create new FileUpload Thing)
//   file_handle (text) = Event's fileHandle result
//   file_url (text)    = Event's URL result
//   file_name (text)   = Event's filename result
//   file_type (text)   = Event's mimetype result
//   uploaded_at (date) = Current date/time

// Step 2 (optional): Show alert "File uploaded successfully"

// Privacy rules check:
// Data tab → Privacy → FileUpload type:
// - 'file_handle' field: visible only to the record's owner (Current User = This FileUpload's owner)
// Without privacy rules, any logged-in user could construct transformation URLs
// for other users' uploaded files

// Transformation URL pattern (use in Image elements):
// https://cdn.filestackcontent.com/resize=width:400,height:300/output=format:webp/{file_handle}
```

**Expected result:** When a user selects files in the Filestack Picker and completes the upload, the file handle and metadata are saved to your Bubble database. The success event fires reliably and the record appears in the App Data tab.

### 5. Use transformation URLs in Image elements and links

This is where Filestack's real value becomes apparent. Instead of storing different image sizes, you construct transformation URLs dynamically in Bubble's expression editor and bind them to Image elements, link URLs, or background image properties.

To display a resized image, go to any Image element's 'Dynamic image' field and set it to a dynamic expression combining a static prefix with the stored file handle:

`https://cdn.filestackcontent.com/resize=width:400,height:300/output=format:webp/` + `Current file record's file_handle`

The result: Filestack's CDN applies the resize and format conversion on the fly, caches the result, and serves it. This counts against your monthly transformation quota (100/month on the free plan).

Common transformation operations you can chain in the URL:
- `resize=width:400,height:300` — resize to fit within dimensions
- `crop=dim:[0,0,400,300]` — crop to specific pixel region
- `output=format:webp` — convert to WebP for smaller file size
- `compress` — apply automatic compression
- `watermark=file:{watermarkHandle}` — overlay a watermark image
- `rotate=deg:90` — rotate the image

Chain multiple operations with `/` between them. The order matters — Filestack applies them left to right.

For non-image files (PDFs, documents), use the file URL directly as a link destination. Filestack also supports generating document previews with its `preview` transformation, but verify this on your plan.

```
// Filestack transformation URL examples — use in Bubble Image element 'Dynamic image' field

// Resize to 400x300 and convert to WebP:
https://cdn.filestackcontent.com/resize=width:400,height:300/output=format:webp/{fileHandle}

// Square crop for avatar images:
https://cdn.filestackcontent.com/crop=dim:[0,0,200,200]/resize=width:200,height:200/{fileHandle}

// Original file download URL (no transformation):
https://cdn.filestackcontent.com/{fileHandle}

// In Bubble dynamic expression:
// Static prefix: "https://cdn.filestackcontent.com/resize=width:400/output=format:webp/"
// + Dynamic value: Current Row's file_handle

// IMPORTANT: Transformation count against your monthly quota
// Free plan: 100 transformations/month
// Cache results in a Bubble field when transformation is expensive or repeated frequently
```

**Expected result:** Image elements in your Bubble app display Filestack-uploaded images at the exact dimensions and format you specified, using dynamic transformation URLs constructed from the stored file handle. Transformations apply without any server code.

### 6. Add API Connector for metadata lookups (and security policy signing if needed)

For situations the plugin doesn't cover — fetching file metadata, checking transformation status, or integrating Filestack features not exposed by the plugin — add Filestack's CDN API to Bubble's API Connector.

Go to Plugins tab → Add plugins → 'API Connector' (by Bubble) → Install. Open the API Connector. Click 'Add another API'. Name it 'Filestack CDN'. Set the base URL to `https://cdn.filestackcontent.com`.

Add a call named 'Get File Metadata':
- Method: GET
- URL: `https://cdn.filestackcontent.com/{your_api_key}/metadata/{fileHandle}`
- Replace `{your_api_key}` with your actual API key as a static URL segment (it's intentionally semi-public)
- Replace `{fileHandle}` with a dynamic parameter
- Click 'Initialize call' with a real file handle from an upload you've already done

For **Filestack Security policies** (only if you've enabled Security in the Filestack dashboard): the HMAC-SHA256 policy signature requires your API Secret. This must be generated server-side — never in a Bubble client-side action or in the API Connector headers, because the secret would appear in browser network requests. Use a Backend Workflow that calls an external signing function (a Cloudflare Worker or Supabase Edge Function that holds the API Secret and returns a computed policy+signature pair). This is an advanced scenario — most Bubble apps do not need Filestack security policies. RapidDev's team has implemented HMAC policy signing for high-security Bubble apps — if you need this, reach out at rapidevelopers.com/contact.

```
// API Connector — Filestack metadata call configuration
{
  "api_name": "Filestack CDN",
  "call_name": "Get File Metadata",
  "method": "GET",
  "url": "https://cdn.filestackcontent.com/{API_KEY}/metadata/{fileHandle}",
  "note": "Replace {API_KEY} with your actual Filestack API key as a static URL segment. Mark as a dynamic parameter if you want to pass it at call time, but static is fine since it is semi-public.",
  "response_example": {
    "mimetype": "image/jpeg",
    "filename": "photo.jpg",
    "size": 245120,
    "width": 1920,
    "height": 1080
  },
  "security_note": "If Filestack Security is enabled on your account, metadata calls also require ?policy=...&signature=... query params. Generate these in a Backend Workflow calling an external signing endpoint — do NOT compute them in client-side Bubble actions."
}
```

**Expected result:** The Filestack CDN API is configured in Bubble's API Connector. File metadata (MIME type, dimensions, file size) can be fetched by file handle and used in Bubble workflows and conditions.

## Best practices

- Store the file handle (the short alphanumeric identifier like `1P89wkysTkePPiSzNHcI`), not the full transformation URL, in your Bubble database. Construct transformation URLs dynamically in display expressions — this gives you flexibility to change image sizes, formats, and effects later without re-uploading files.
- Set privacy rules on data types storing file handles. Data tab → Privacy → create a rule that restricts the `file_handle` field to the record's owner. Without this, any logged-in user can read another user's file handle and access their files.
- Keep the Filestack API key in plugin settings — never hardcode it in Bubble page text elements, conditions, or workflow input values. While the API key is semi-public by design, using plugin settings makes it easier to rotate and keeps your app structure clean.
- Keep the Filestack API Secret (if you use security policies) strictly server-side in an external signing function. Never place it in Bubble's API Connector headers, page elements, or any client-reachable value. If it appears in browser network requests, rotate it immediately in the Filestack dashboard.
- Cache frequently-used transformation results. If your app displays the same image thumbnail in multiple places, store the transformation URL as a Bubble text field after the first successful display. Repeated dynamic construction of identical transformation URLs may count against your monthly quota unnecessarily.
- Configure accepted file types and max file size in the Picker element settings, not just in server-side validation. This provides immediate user feedback before the upload begins and reduces wasted uploads from unsupported file types.
- For production apps with sensitive documents, consider routing Filestack uploads to your own S3 bucket using Filestack's 'Intelligent Ingestion' feature in the Filestack dashboard. This stores files in your infrastructure while keeping the Picker widget experience — the best of both approaches.
- Evaluate plugin maintenance status before building. Check the plugin's last-updated date and review recent community discussions. A plugin that hasn't been updated in 18+ months is a risk in a production app — plan for the API Connector fallback approach if the plugin becomes unreliable.

## Use cases

### Multi-source file upload with cloud picker

Let users upload files from their desktop, Google Drive, Dropbox, or any URL — all through a single Filestack Picker modal. The Picker handles authentication with each cloud source. Your Bubble app only handles the success event, saving the returned file handle and URL to the user's record. No complex upload flow to build.

### On-the-fly image resizing and format conversion

Display user-uploaded profile photos, product images, or portfolio pieces at exactly the size and format your design requires — without storing multiple variants. Store the file handle once; construct transformation URLs dynamically in Bubble Image elements. Convert to WebP for performance, crop to a square avatar, or generate thumbnails, all via URL parameters.

### Document upload with virus scanning

Accept document uploads from users (PDFs, Word files, spreadsheets) with optional virus scanning built into the Filestack upload pipeline. Filestack's CDN processes the file and can be configured to reject infected uploads before they reach your application. Store the file handle in a Bubble data type for later retrieval.

## Troubleshooting

### The Filestack Picker modal does not open when the upload button is clicked

Cause: The plugin's trigger action is not correctly set up in the workflow, the plugin element isn't on the page, or the plugin failed to load due to an API key configuration error.

Solution: 1. Confirm the Filestack Picker element is placed on the page (can be invisible/0×0 but must be present). 2. In the button's workflow, check that the action calls the Filestack plugin's 'Open Picker' or equivalent action targeting the correct Picker element. 3. Open the browser console (F12 → Console) and look for Filestack SDK errors — often related to an invalid or missing API key. 4. Verify the API key in the plugin settings is correct and matches your Filestack dashboard.

### Upload success event fires but file handle is empty or the event data fields are missing

Cause: The plugin's event data structure may differ from what the workflow expects, or the plugin version doesn't expose the file handle in the event result.

Solution: Check the plugin's documentation for the exact field names returned in the upload success event. Common variations: `handle`, `fileHandle`, `url`, `cdnUrl`, `filename`. In Bubble's workflow editor, when binding to the event result, use the dropdown to see what fields the plugin actually exposes — they will appear as 'Result of event X's [field name]'. If the handle is not exposed, check if the plugin has been updated recently.

### Filestack API Connector returns 'missing security' (403) when initializing the metadata call

Cause: Filestack Security policies are enabled on your account. Metadata and other CDN API calls require a policy and HMAC-SHA256 signature when security is enabled.

Solution: For development: go to your Filestack dashboard → Security tab and temporarily disable security policies. Re-initialize the API Connector call. For production: build a signing proxy (external server-side function) that computes the policy and signature using your API Secret, and have Bubble's API Connector call the proxy instead of Filestack directly.

### Transformation URLs stop working or return errors after the free plan transformation quota is reached

Cause: The Filestack free plan includes only 100 transformations per month. Each unique transformation URL that is rendered (not cached) counts against this quota.

Solution: 1. Upgrade to a Filestack paid plan for higher transformation quotas. 2. Cache transformation URLs in your Bubble database — after generating a thumbnail URL once, store it as a field and use that stored URL for subsequent displays instead of constructing the URL dynamically every time (which may re-request the transformation). 3. Use Filestack's CDN caching by keeping transformation URLs consistent — the same transformation applied to the same handle is cached after first request.

### Plugin in the Bubble marketplace appears unmaintained and the Filestack Picker stops working after a Filestack API update

Cause: Community plugins are third-party maintained and may lag behind Filestack API version changes. Filestack has updated its Picker and SDK versions over time.

Solution: Check the plugin's Bubble forum discussion thread for recent activity. If the plugin author hasn't responded to issues in several months, switch to the API Connector fallback approach for metadata operations, and consider using an HTML element with the Filestack Picker JavaScript embed code for the upload UI — inserting the official Filestack Picker script directly gives you access to the latest SDK version.

## Frequently asked questions

### Do I need a paid Bubble plan to use Filestack?

No — for basic plugin-based uploads using the Filestack Picker, any Bubble plan works, including Free. Backend Workflows (paid Bubble plan required) are only needed if you implement Filestack security policy signing via an external proxy. The plugin handles uploads client-side without Backend Workflows.

### Is the Filestack API key safe to use in a Bubble plugin or page?

Yes — the API key (also called the App key) is intentionally semi-public. Filestack designed it to be embedded in frontend picker code. It appears in page source, in network requests, and in transformation URLs. It controls which Filestack account files are uploaded to, but Filestack's rate limiting and account-level controls handle abuse prevention. However, treat it with basic care: store it in plugin settings rather than hardcoding it in page text. The API Secret is a completely different credential — it is fully private and must never appear in client-side code.

### What happens to my files if I cancel my Filestack subscription?

Filestack stores files on their CDN by default. If your account is cancelled or downgraded, access to those files depends on Filestack's terms of service — verify the data retention policy at filestack.com before relying on Filestack as your primary storage for important files. For data ownership, use Filestack's 'Intelligent Ingestion' to route uploads to your own S3 bucket: Filestack Dashboard → App Settings → Storage → add your S3 bucket as the storage destination.

### How does the free plan's 100 transformation/month limit work in practice?

Each unique transformation URL that is fetched from Filestack's CDN counts as one transformation. However, Filestack caches the result — so if 100 users view the same resized image (same transformation URL), it typically counts as one transformation (the first fetch) not 100. The quota is meaningful when you have many unique images each displayed at unique dimensions. For high-traffic apps, upgrade to a paid plan or implement your own caching by storing transformation URLs in Bubble after first use.

### Can Filestack replace raw object storage like S3 entirely?

For many Bubble apps, yes — Filestack handles uploads, CDN delivery, and image processing in one service. The main limitations: files are stored on Filestack's infrastructure by default (not yours), and pricing scales with uploads and transformations rather than storage volume. For apps primarily concerned with hosting large volumes of binary data, raw storage (S3, B2, Wasabi) is cheaper at scale. For apps where upload UX and image processing matter more than storage costs, Filestack provides more value.

### What file sources does the Filestack Picker support?

The Filestack Picker supports: local device files (drag-and-drop and file browser), URL imports (paste any URL to upload a file from the web), Google Drive, Dropbox, OneDrive, Box, GitHub, GitLab, Instagram, Facebook, Flickr, Google Photos, and more. The specific sources available depend on your Filestack plan and which sources you enable in the Picker configuration. Each cloud source handles its own OAuth authentication inside the Picker modal — your Bubble app only receives the resulting file handle.

---

Source: https://www.rapidevelopers.com/bubble-integrations/filestack
© RapidDev — https://www.rapidevelopers.com/bubble-integrations/filestack
