# Configuring Storage in Supamode

> Configure file uploads for your database columns. Connect columns to Supabase Storage buckets with custom path templates, file size limits, and replacement options.

*Canonical: https://makerkit.dev/docs/supamode/configuration/storage*

---

Supamode integrates with Supabase Storage to handle file uploads directly from the Data Explorer. When you configure a column as a file type, Supamode automatically handles uploads, generates paths, and stores references in your database.

## How Storage Integration Works

1. You configure a column as a file type (image, file, audio, video)
2. When editing a record, Supamode shows a file uploader instead of a text input
3. On upload, the file goes to your configured Supabase Storage bucket
4. The file path (URL or reference) is stored in the database column

This lets your team upload files through the admin UI without building custom upload flows.

## Configuring Storage for a Column

Navigate to **Settings > Tables**, select a table, then click on a column to edit its settings.

{% img src="/images/supamode/storage-file-configuration.webp" alt="Storage configuration panel showing bucket, path template, and size options" width="1450" height="1800" /%}

### UI Data Type

Set the column's **UI Data Type** to one of:

| Type | Use Case | Preview in Data Explorer |
|------|----------|-------------------------|
| **File** | Documents, PDFs, any file | File name with download link |
| **Image** | Photos, graphics | Thumbnail preview |
| **Audio** | Music, podcasts | Audio player |
| **Video** | Videos, recordings | Video player |

Once set, the column configuration expands to show storage options.

### Bucket Name

The **Bucket Name** must match an existing bucket in your Supabase Storage.

**Prerequisites:**
1. Create the bucket in Supabase Dashboard > Storage
2. Configure the bucket's privacy settings (public/private)
3. Set up RLS policies if the bucket is private
4. Enter the exact bucket name in Supamode

```
avatars
documents
media
uploads
```

{% alert type="warning" title="Bucket Must Exist" %}
Supamode does not create buckets. If the bucket doesn't exist in Supabase Storage, uploads will fail. Create buckets before configuring storage columns.
{% /alert %}

### Storage Path Template

The **Storage Path Template** determines where files are stored within the bucket. Use placeholders to create dynamic paths.

**Available placeholders:**

| Placeholder | Value | Example Output |
|-------------|-------|----------------|
| `{{timestamp}}` | Unix timestamp | `1705689600` |
| `{{filename}}` | Original filename (without extension) | `profile-photo` |
| `{{extension}}` | File extension | `png` |
| `{{column_name}}` | Value from another column | `user-123` |

**Example templates:**

```
# Simple - files in root with timestamp
{{timestamp}}-{{filename}}.{{extension}}
→ 1705689600-profile-photo.png

# Organized by user ID column
users/{{user_id}}/{{filename}}.{{extension}}
→ users/abc-123/profile-photo.png

# By date and type
uploads/{{timestamp}}/{{filename}}.{{extension}}
→ uploads/1705689600/document.pdf

# Custom folder structure
avatars/{{user_id}}/avatar.{{extension}}
→ avatars/abc-123/avatar.webp
```

**Path rules:**
- If the template doesn't include `{{extension}}`, Supamode treats the path as a folder and appends the original filename
- Use column references (`{{column_name}}`) for values from the same record
- Paths are case-sensitive

### Max File Size

The **Max File Size** sets a client-side limit on upload size (in bytes).

| Size | Bytes |
|------|-------|
| 1 MB | 1048576 |
| 5 MB | 5242880 |
| 10 MB | 10485760 |
| 50 MB | 52428800 |

{% alert type="default" title="Also Configure in Supabase" %}
This is a client-side check only. Configure the same limit in your Supabase Storage bucket settings (Settings > Upload file size limit) for server-side enforcement.
{% /alert %}

### Replace Existing Files

When **Replace Existing Files** is enabled, uploading a new file to the same path overwrites the previous file.

**When to enable:**
- User avatars (one file per user)
- Document that should always be the latest version
- Paths that are deterministic (like `avatars/{{user_id}}/avatar.{{extension}}`)

**When to disable:**
- Upload history should be preserved
- Multiple files per record are expected
- Paths include timestamps (files are unique anyway)

## Storage Permissions

Users need storage permissions to upload, view, or delete files. Configure these in [Roles and Permissions](./permissions).

**Required permissions by action:**

| Action | Permission Needed |
|--------|-------------------|
| View/download files | `select` on the storage bucket |
| Upload new files | `insert` on the storage bucket |
| Replace files | `update` on the storage bucket |
| Delete files | `delete` on the storage bucket |

**Example permission:**
```
Type: Data
Scope: Storage
Bucket: avatars
Path: users/*
Action: * (all operations)
```

## Troubleshooting

### Upload Fails with "Bucket Not Found"

1. Verify the bucket exists in Supabase Dashboard > Storage
2. Check the bucket name matches exactly (case-sensitive)
3. Ensure the bucket is not disabled

### Upload Fails with "Permission Denied"

1. Check the user's role has storage permissions for this bucket
2. Verify the bucket's RLS policies allow uploads
3. For public buckets, confirm public access is enabled

### Files Not Displaying

1. Verify the column contains a valid storage path/URL
2. Check the bucket's privacy settings
3. For private buckets, ensure signed URLs are being generated

### Path Template Not Working

1. Check placeholder syntax: `{{column_name}}` not `{column_name}`
2. Verify referenced columns exist in the same table
3. Ensure the column value is not null when uploading

{% faq
   title="Frequently Asked Questions"
   items=[
     {"question": "Can I use storage with private buckets?", "answer": "Yes. Supamode generates signed URLs for private bucket files when displaying them in the Data Explorer. Users still need appropriate storage permissions."},
     {"question": "What happens to old files when I upload a replacement?", "answer": "If Replace Existing Files is enabled, the old file is deleted. If disabled, the upload fails if a file already exists at that path. There's no automatic versioning."},
     {"question": "Can a column reference files from multiple buckets?", "answer": "No. Each storage-configured column is linked to one bucket. If you need multiple buckets, use separate columns."},
     {"question": "How do I delete files when deleting records?", "answer": "Supamode does not automatically delete storage files when records are deleted. Implement cleanup via database triggers or a scheduled job if needed."},
     {"question": "What file types are allowed?", "answer": "Supamode allows any file type that your Supabase Storage bucket accepts. Configure allowed MIME types in your bucket settings if you need restrictions."}
   ]
/%}
