Supabase Storage Integration
Supabase Storage is an S3-compatible object storage service built on top of Supabase’s open-source platform. Sveltia CMS supports Supabase Storage as a media storage backend with direct browser-to-storage uploads using AWS Signature Version 4 — no backend proxy is required.
Requirements
- A Supabase project with a storage bucket created.
- An S3 access key pair generated from your project’s storage settings (see Credentials below).
CSP
If your site uses a Content Security Policy (CSP), you need to allow the Supabase Storage endpoint. See Content Security Policy below for details.
Setup
Credentials
Supabase Storage supports S3-compatible authentication using project-scoped credentials. Generate an access key pair via Supabase Dashboard > [project] > Storage > S3 Configuration.
WARNING
S3 access keys provide full access to all S3 operations across all buckets and bypass Row Level Security (RLS) policies. They are intended for server-side use. Never commit the Secret Access Key to your repository.
The resulting Access Key ID goes in access_key_id in your config. The Secret Access Key is entered by users in the CMS UI when they access the media library for the first time — it is never stored in config.
Project ID and Region
The Project ID (shown in Project Settings > General) goes in project_id. The Region is also shown on the Storage S3 configuration page and follows the format used on that page (e.g. us-east-1, eu-west-2).
Public Read Access
Asset preview and download URLs point directly to the Supabase public storage URL (https://{project_id}.supabase.co/storage/v1/object/public/{bucket}/{key}), so the bucket must be set to Public. You can do this in the bucket settings.
CORS
Supabase Storage’s S3 endpoint allows cross-origin requests by default for authenticated operations. If you encounter CORS issues, check your project’s network restrictions under Supabase Dashboard > Settings > Network.
Configuration
Here’s an example configuration for Supabase Storage:
media_libraries:
supabase_storage:
access_key_id: your_access_key_id
project_id: abcdefghijklmnopqrst
bucket: my-bucket
region: us-east-1
prefix: cms-uploads/ # Optional
public_url: https://my-cdn.example.com # Optional, see Custom Domain below[media_libraries.supabase_storage]
access_key_id = "your_access_key_id"
project_id = "abcdefghijklmnopqrst"
bucket = "my-bucket"
region = "us-east-1"
prefix = "cms-uploads/"
public_url = "https://my-cdn.example.com"{
"media_libraries": {
"supabase_storage": {
"access_key_id": "your_access_key_id",
"project_id": "abcdefghijklmnopqrst",
"bucket": "my-bucket",
"region": "us-east-1",
"prefix": "cms-uploads/",
"public_url": "https://my-cdn.example.com"
}
}
}{
media_libraries: {
supabase_storage: {
access_key_id: 'your_access_key_id',
project_id: 'abcdefghijklmnopqrst',
bucket: 'my-bucket',
region: 'us-east-1',
prefix: 'cms-uploads/', // Optional
public_url: 'https://my-cdn.example.com', // Optional
},
},
}WARNING
Do not write your Secret Access Key in the configuration file, as it should be kept confidential and not exposed in client-side code. Users will be prompted to enter the key when they use the storage for the first time, which will be stored securely in the browser’s local storage.
Configuration Properties
| Property | Required | Description |
|---|---|---|
access_key_id | Yes | Supabase S3 Access Key ID. Safe to store in config. |
project_id | Yes | Supabase Project ID. Used to construct the S3 API endpoint and public URL. |
bucket | Yes | The storage bucket name. |
region | No | The project region shown on the Storage S3 configuration page, e.g. eu-central-1. Defaults to us-east-1. |
prefix | No | Path prefix within the bucket, e.g. uploads/. A trailing slash is added if missing. |
public_url | No | Custom domain URL for asset previews. See Custom Domain below. |
Custom Domain
By default, asset URLs use the Supabase public storage URL (https://{project_id}.supabase.co/storage/v1/object/public/{bucket}/{key}). To serve assets via a custom domain, set public_url to the same URL on your domain, including the /storage/v1/object/public/{bucket} path, as the object key is appended to it directly:
public_url: 'https://media.example.com/storage/v1/object/public/my-bucket'Content Security Policy
API calls (list, upload) go to https://{project_id}.storage.supabase.co. Asset URLs use https://{project_id}.supabase.co by default:
connect-src https://abcdefghijklmnopqrst.storage.supabase.co
https://abcdefghijklmnopqrst.supabase.co;
img-src https://abcdefghijklmnopqrst.supabase.co;If using a custom domain via public_url:
connect-src https://abcdefghijklmnopqrst.storage.supabase.co
https://media.example.com;
img-src https://media.example.com;Replace abcdefghijklmnopqrst with your actual Project ID.
The asset host must be in connect-src because the Download and Copy buttons and the text preview in the Asset Library fetch the file from its public URL. For the same reason, a custom domain must also send CORS headers that allow the CMS origin, otherwise downloads fail.
See the CSP documentation for more details.
Accessing the Storage
There are two ways to use Supabase Storage in Sveltia CMS:
File and Image Fields
When editing content entries, users can use File and Image fields to upload and select media on Supabase Storage directly within the entry editor. After entering the Secret Access Key in the CMS UI when prompted, users can upload new media directly to your bucket or select existing media.
Asset Library
Supabase Storage also appears under External Locations in the Asset Library, where users can browse, search, sort and filter the files in your bucket, and upload, rename, replace, download or delete them without leaving the CMS. The files and folders are browsed folder by folder: subfolders are listed ahead of the files, uploads go to the folder being viewed, and folders can be created, renamed and deleted.