mirror of
https://github.com/supabase/supabase.git
synced 2026-07-02 15:34:36 +08:00
* chore: update links * chore: move duplicate sections into components. * fix: auth-helpers-nextjs docs * chore: rename to _partials. Co-authored-by: Copple <10214025+kiwicopple@users.noreply.github.com>
376 lines
11 KiB
Plaintext
376 lines
11 KiB
Plaintext
---
|
|
id: storage
|
|
title: Storage
|
|
description: Use Supabase to store and serve files.
|
|
sidebar_label: Overview
|
|
---
|
|
|
|
import Tabs from '@theme/Tabs'
|
|
import TabItem from '@theme/TabItem'
|
|
|
|
Supabase Storage makes it simple to store and serve large files.
|
|
|
|
### Files
|
|
|
|
Files can be any sort of media file. This includes images, GIFs, and videos. It is best practice to store files outside of your database because of their sizes.
|
|
|
|
### Folders
|
|
|
|
Folders are a way to organize your files (just like on your computer).
|
|
There is no right or wrong way to
|
|
organize your files. You can store them in whichever folder structure suits your project.
|
|
|
|
### Buckets
|
|
|
|
Buckets are distinct containers for files and folders. You can think of them like "super folders".
|
|
Generally you would create distinct buckets for different Security and Access Rules. For example, you might
|
|
keep all video files in a "video" bucket, and profile pictures in an "avatar" bucket.
|
|
|
|
<div class="video-container">
|
|
<iframe
|
|
src="https://www.youtube-nocookie.com/embed/J9mTPY8rIXE"
|
|
frameBorder="1"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowFullScreen
|
|
></iframe>
|
|
</div>
|
|
|
|
## Getting started
|
|
|
|
This is a quick guide that shows the basic functionality of Supabase Storage. Find a full
|
|
[example application in GitHub](https://github.com/supabase/supabase/tree/master/examples/user-management/nextjs-ts-user-management),
|
|
which you can deploy yourself.
|
|
|
|
[](https://vercel.com/new/git/external?repository-url=https%3A%2F%2Fgithub.com%2Fsupabase%2Fsupabase%2Ftree%2Fmaster%2Fexamples%2Fuser-management%2Fnextjs-ts-user-management&project-name=supabase-user-management&repository-name=supabase-user-management&demo-title=Supabase%20User%20Management&demo-description=An%20example%20web%20app%20using%20Supabase%20and%20Next.js&demo-url=https%3A%2F%2Fsupabase-nextjs-ts-user-management.vercel.app&demo-image=https%3A%2F%2Fi.imgur.com%2FZ3HkQqe.png&integration-ids=oac_jUduyjQgOyzev1fjrW83NYOv&external-id=nextjs-user-management)
|
|
|
|
:::note
|
|
File, Folder, and Bucket names **must follow** [AWS object key naming guidelines](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html) and avoid use of any other characters.
|
|
:::
|
|
|
|
### Create a bucket
|
|
|
|
You can create a bucket using the Supabase Dashboard.
|
|
Since the storage is interoperable with your Postgres database, you can also use SQL or our
|
|
client libraries. Here we create a bucket called "avatars":
|
|
|
|
<Tabs
|
|
groupId="storage-tabs"
|
|
defaultValue="dashboard"
|
|
values={[
|
|
{label: 'Dashboard', value: 'dashboard'},
|
|
{label: 'SQL', value: 'sql'},
|
|
{label: 'JavaScript', value: 'javascript'},
|
|
{label: 'Dart', value: 'dart'},
|
|
]}>
|
|
<TabItem value="dashboard">
|
|
|
|
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
|
|
2. Click **New Bucket** and enter a name for the bucket.
|
|
3. Click **Create Bucket**.
|
|
|
|
</TabItem>
|
|
<TabItem value="sql">
|
|
|
|
```sql
|
|
-- Use Postgres to create a bucket.
|
|
|
|
insert into storage.buckets (id, name)
|
|
values ('avatars', 'avatars');
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem value="javascript">
|
|
|
|
```js
|
|
// Use the JS library to create a bucket.
|
|
|
|
const { data, error } = await supabase.storage.createBucket('avatars')
|
|
```
|
|
|
|
[Reference.](/docs/reference/javascript/storage-createbucket)
|
|
|
|
</TabItem>
|
|
<TabItem value="dart">
|
|
|
|
```dart
|
|
void main() async {
|
|
final client = SupabaseClient('supabaseUrl', 'supabaseKey');
|
|
|
|
final storageResponse = await client
|
|
.storage
|
|
.createBucket('avatars');
|
|
}
|
|
```
|
|
|
|
[Reference.](https://pub.dev/documentation/storage_client/latest/storage_client/SupabaseStorageClient/createBucket.html)
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
### Upload a file
|
|
|
|
You can upload a file from the Dashboard, or within a browser using our JS libraries.
|
|
|
|
<Tabs
|
|
groupId="storage-tabs"
|
|
defaultValue="dashboard"
|
|
values={[
|
|
{label: 'Dashboard', value: 'dashboard'},
|
|
{label: 'JavaScript', value: 'javascript'},
|
|
{label: 'Dart', value: 'dart'},
|
|
]}>
|
|
<TabItem value="dashboard">
|
|
|
|
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
|
|
2. Select the bucket you want to upload the file to.
|
|
3. Click **Upload File**.
|
|
4. Select the file you want to upload.
|
|
|
|
</TabItem>
|
|
<TabItem value="javascript">
|
|
|
|
```js
|
|
const avatarFile = event.target.files[0]
|
|
const { data, error } = await supabase.storage
|
|
.from('avatars')
|
|
.upload('public/avatar1.png', avatarFile)
|
|
```
|
|
|
|
[Reference.](/docs/reference/javascript/storage-from-upload)
|
|
|
|
</TabItem>
|
|
<TabItem value="dart">
|
|
|
|
```dart
|
|
void main() async {
|
|
final client = SupabaseClient('supabaseUrl', 'supabaseKey');
|
|
|
|
// Create file `example.txt` and upload it in `public` bucket
|
|
final file = File('example.txt');
|
|
file.writeAsStringSync('File content');
|
|
final storageResponse = await client
|
|
.storage
|
|
.from('public')
|
|
.upload('example.txt', file);
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
### Download a file
|
|
|
|
You can download a file from the Dashboard, or within a browser using our JS libraries.
|
|
|
|
<Tabs
|
|
groupId="storage-tabs"
|
|
defaultValue="dashboard"
|
|
values={[
|
|
{label: 'Dashboard', value: 'dashboard'},
|
|
{label: 'JavaScript', value: 'javascript'},
|
|
{label: 'Dart', value: 'dart'},
|
|
]}>
|
|
<TabItem value="dashboard">
|
|
|
|
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
|
|
2. Select the bucket that contains the file.
|
|
3. Select the file that you want to download.
|
|
4. Click **Download**.
|
|
|
|
</TabItem>
|
|
<TabItem value="javascript">
|
|
|
|
```js
|
|
// Use the JS library to download a file.
|
|
|
|
const { data, error } = await supabase.storage
|
|
.from('avatars')
|
|
.download('public/avatar1.png')
|
|
```
|
|
|
|
[Reference.](/docs/reference/javascript/storage-from-download)
|
|
|
|
</TabItem>
|
|
<TabItem value="dart">
|
|
|
|
```dart
|
|
void main() async {
|
|
final client = SupabaseClient('supabaseUrl', 'supabaseKey');
|
|
|
|
final storageResponse = await client
|
|
.storage
|
|
.from('public')
|
|
.download('example.txt');
|
|
}
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
### Add security rules
|
|
|
|
To restrict access to your files you can use either the Dashboard or SQL.
|
|
|
|
<Tabs
|
|
groupId="storage-tabs"
|
|
defaultValue="dashboard"
|
|
values={[
|
|
{label: 'Dashboard', value: 'dashboard'},
|
|
{label: 'SQL', value: 'sql'}
|
|
]}>
|
|
<TabItem value="dashboard">
|
|
|
|
1. Go to the [Storage](https://app.supabase.com/project/_/storage/buckets) page in the Dashboard.
|
|
2. Click **Policies** in the sidebar.
|
|
3. Click **Add Policies** in the `OBJECTS` table to add policies for Files. You can also create policies for Buckets.
|
|
4. Choose whether you want the policy to apply to downloads (SELECT), uploads (INSERT), updates (UPDATE), or deletes (DELETE).
|
|
5. Give your policy a unique name.
|
|
6. Write the policy using SQL.
|
|
|
|
</TabItem>
|
|
<TabItem value="sql">
|
|
|
|
```sql
|
|
-- Use SQL to create a policy.
|
|
|
|
create policy "Public Access"
|
|
on storage.objects for select
|
|
using ( bucket_id = 'public' );
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
## Public and Private Buckets
|
|
|
|
Storage buckets are private by default.
|
|
|
|
For private buckets, you can access objects via the [download](/docs/reference/javascript/storage-from-download) method. This corresponds to `/object/auth/` API endpoint.
|
|
Alternatively, you can create a publicly shareable URL with an expiry date using the [createSignedUrl](/docs/reference/javascript/storage-from-createsignedurl) method
|
|
which calls the `/object/sign/` API.
|
|
|
|
For public buckets, you can access the assets directly without a token or an Authorisation header. The [getPublicUrl](/docs/reference/javascript/storage-from-getpublicurl)
|
|
helper method returns the full public URL for an asset. This calls the `/object/public/` API endpoint internally. While no authorization is required for accessing objects in a public bucket, proper [access control](#access-control) is required for other operations like uploading, deleting objects from public buckets as well.
|
|
|
|
Public buckets also tend to have [better performance](/docs/guides/storage-cdn#public-vs-private-buckets).
|
|
|
|
<details>
|
|
<summary>Advanced: reverse proxy</summary>
|
|
The URLs returned are proxied through the API Proxy. They are prefixed by <code>/storage/v1</code>.
|
|
|
|
For example, on the hosted Platform they will be
|
|
|
|
<code>https://[project_ref].supabase.co/storage/v1/object/public/[id]</code>
|
|
|
|
You can access the storage API directly with the same endpoint. See the <a href="https://supabase.github.io/storage-api">API docs</a> for a full list of operations available.
|
|
|
|
</details>
|
|
|
|
---
|
|
|
|
## Access control
|
|
|
|
Supabase Storage is integrated with your [Postgres Database](/docs/guides/database).
|
|
This means that you can use the same [Row Level Security Policies](/docs/guides/auth#policies)
|
|
for managing access to your files. Supabase Storage stores metadata in the `objects` and `buckets` table in the storage schema. To allow read access to files, the RLS policy must allow users to `SELECT` the `objects` table and for uploading a new object, the RLS policy must grant users access to `INSERT` into the `objects` table and so on. The mapping between the different API calls and the database permissions required is documented in the [Reference docs](/docs/reference/javascript/storage-createbucket).
|
|
|
|
:::note
|
|
|
|
Access control for Storage is mapped to CRUD operations on the `buckets` and `objects` table via RLS policies.
|
|
|
|
:::
|
|
|
|
## Helpers
|
|
|
|
Supabase Storage provides SQL helper functions which you can use in your database queries and
|
|
policies.
|
|
|
|
---
|
|
|
|
#### `storage.filename()`
|
|
|
|
Returns the name of a file.
|
|
|
|
```sql
|
|
select storage.filename(name)
|
|
from storage.objects;
|
|
```
|
|
|
|
For example, if your file is stored in `public/subfolder/avatar.png` it would return:
|
|
|
|
`'avatar.png'`
|
|
|
|
---
|
|
|
|
#### `storage.foldername()`
|
|
|
|
Returns an array path, with all of the subfolders that a file belongs to.
|
|
|
|
```sql
|
|
select storage.foldername(name)
|
|
from storage.objects;
|
|
```
|
|
|
|
For example, if your file is stored in `public/subfolder/avatar.png` it would return:
|
|
|
|
`[ 'public', 'subfolder' ]`
|
|
|
|
---
|
|
|
|
#### `storage.extension()`
|
|
|
|
Returns the extension of a file.
|
|
|
|
```sql
|
|
select storage.extension(name)
|
|
from storage.objects;
|
|
```
|
|
|
|
For example, if your file is stored in `public/subfolder/avatar.png` it would return:
|
|
|
|
`'png'`
|
|
|
|
---
|
|
|
|
## Policy examples
|
|
|
|
Here are some examples of storage policies.
|
|
|
|
### Allow public access to a bucket
|
|
|
|
```sql
|
|
-- 1. Allow public access to any files in the "public" bucket
|
|
create policy "Public Access"
|
|
on storage.objects for select
|
|
using ( bucket_id = 'public' );
|
|
```
|
|
|
|
### Allow logged-in access to a bucket
|
|
|
|
```sql
|
|
-- 1. Allow logged-in access to any files in the "restricted" bucket
|
|
create policy "Restricted Access"
|
|
on storage.objects for select
|
|
using (
|
|
bucket_id = 'restricted'
|
|
and auth.role() = 'authenticated'
|
|
);
|
|
```
|
|
|
|
### Allow individual access to a file
|
|
|
|
```sql
|
|
-- 1. Allow a user to access their own files
|
|
create policy "Individual user Access"
|
|
on storage.objects for select
|
|
using ( auth.uid() = owner );
|
|
```
|
|
|
|
## See also
|
|
|
|
- Read more about Supabase Storage in the [blog post](https://supabase.com/blog/supabase-storage)
|
|
- [Supabase Storage on GitHub](https://github.com/supabase/storage-api)
|
|
- [Swagger API documentation](https://supabase.github.io/storage-api)
|
|
- Official [JavaScript](/docs/reference/javascript/storage-createbucket) and [Dart](/docs/reference/dart/storage-createbucket) documentation
|
|
- [Community libraries](https://github.com/supabase-community)
|