---
url: /en/docs/media/supabase-storage.md
description: >-
  Use Supabase Storage as an external media storage provider in Sveltia CMS for
  S3-compatible cloud storage with fine-grained access control.
---

# Supabase Storage Integration

[Supabase Storage](https://supabase.com/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](#credentials) below).

### CSP

If your site uses a Content Security Policy (CSP), you need to allow the Supabase Storage endpoint. See [Content Security Policy](#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:

::: code-group

```yaml [YAML]
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
```

```toml [TOML]
[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"
```

```json [JSON]
{
  "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"
    }
  }
}
```

```js [JavaScript]
{
  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](#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:

```yaml
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](/en/docs/ui/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](/en/docs/security#setting-up-content-security-policy) 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](/en/docs/fields/file) and [Image](/en/docs/fields/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](/en/docs/ui/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](/en/docs/ui/asset-library#folders-on-external-locations): subfolders are listed ahead of the files, uploads go to the folder being viewed, and folders can be created, renamed and deleted.
