Skip to content

Updated

Standard Uploads

Learn how to upload files to Supabase Storage.

Uploading

The standard file upload method is ideal for small files that are not larger than 6MB.

You implement file uploads with the supabase-js SDK using the traditional multipart/form-data format. Here's an example of how to upload a file using the standard upload method:

import { } from '@supabase/supabase-js'
// Create Supabase client
const = ('your_project_url', 'your_supabase_api_key')
// Upload file using standard upload
async function () {
const { , } = await ..('bucket_name').('file_path', )
if () {
// Handle error
} else {
// Handle success
}
}
// Upload file using standard upload
Future<void> uploadFile(File file) async {
await supabase.storage.from('bucket_name').upload('file_path', file);
}
import Supabase
// Create Supabase client
let supabase = SupabaseClient(supabaseURL: URL(string: "your_project_url")!, supabaseKey: "your_supabase_api_key")
try await supabase.storage.from("bucket_name").upload(path: "file_path", file: file)
supabase.storage.from("bucket_name").upload("file_path", bytes)
//Or on JVM/Android: (This will stream the data from the file to supabase)
supabase.storage.from("bucket_name").upload("file_path", file)
response = supabase.storage.from_('bucket_name').upload('file_path', file)
await supabase.Storage.From("bucket_name").Upload("local_file_path", "file_path");
curl -X POST "https://{your_project_ref}.supabase.co/storage/v1/object/{bucket_name}/{file_path}" \
-H "apikey: {your_anon_key}" \
-H "Authorization: Bearer {your_jwt_token}" \
--data-binary "@/local/path/to/your/file.ext"

Overwriting files

When uploading a file to a path that already exists, the default behavior is to return a 400 Asset Already Exists error. If you want to overwrite a file on a specific path you can set the upsert options to true or using the x-upsert header.

// Create Supabase client
const = ('your_project_url', 'your_supabase_api_key')
await ..('bucket_name').('file_path', , {
: true,
})
await supabase.storage.from('bucket_name').upload(
'file_path',
file,
fileOptions: const FileOptions(upsert: true),
);
import Supabase
// Create Supabase client
let supabase = SupabaseClient(supabaseURL: URL(string: "your_project_url")!, supabaseKey: "your_supabase_api_key")
try await supabase.storage.from("bucket_name")
.upload(
path: "file_path",
file: file,
options: FileOptions(
upsert: true
)
)
supabase.storage.from("bucket_name").upload("file_path", bytes) {
upsert = true
}
response = supabase.storage.from_('bucket_name').upload('file_path', file, {
'upsert': 'true',
})
await supabase.Storage
.From("bucket_name")
.Upload("local_file_path", "file_path", new FileOptions { Upsert = true });
curl -X POST "https://{your_project_ref}.supabase.co/storage/v1/object/{bucket_name}/{file_path}" \
-H "apikey: {your_anon_key}" \
-H "Authorization: Bearer {your_jwt_token}" \
-H "x-upsert: true" \
--data-binary "@/local/path/to/your/file.ext"

We do advise against overwriting files when possible, as our Content Delivery Network will take sometime to propagate the changes to all the edge nodes leading to stale content. Uploading a file to a new path is the recommended way to avoid propagation delays and stale content.

Content type

By default, Storage will assume the content type of an asset from the file extension. If you want to specify the content type for your asset, pass the contentType option during upload.

// Create Supabase client
const = ('your_project_url', 'your_supabase_api_key')
await ..('bucket_name').('file_path', , {
: 'image/jpeg',
})
await supabase.storage.from('bucket_name').upload(
'file_path',
file,
fileOptions: const FileOptions(contentType: 'image/jpeg'),
);
import Supabase
// Create Supabase client
let supabase = SupabaseClient(supabaseURL: URL(string: "your_project_url")!, supabaseKey: "your_supabase_api_key")
try await supabase.storage.from("bucket_name")
.upload(
path: "file_path",
file: file,
options: FileOptions(
contentType: "image/jpeg"
)
)
supabase.storage.from("bucket_name").upload("file_path", bytes) {
contentType = ContentType.Image.JPEG
}
response = supabase.storage.from_('bucket_name').upload('file_path', file, {
'content-type': 'image/jpeg',
})
await supabase.Storage
.From("bucket_name")
.Upload(
"local_file_path",
"file_path",
new FileOptions { ContentType = "image/jpeg" },
inferContentType: false);
curl -X POST "https://{your_project_ref}.supabase.co/storage/v1/object/{bucket_name}/{file_path}" \
-H "apikey: {your_anon_key}" \
-H "Authorization: Bearer {your_jwt_token}" \
-H "Content-Type: {Content-Type}" \
--data-binary "@/local/path/to/your/file.ext"

Concurrency

When two or more clients upload a file to the same path, the first client to complete the upload will succeed and the other clients will receive a 400 Asset Already Exists error. If you provide the x-upsert header the last client to complete the upload will succeed instead.

Presigned uploads

Standard uploads also support using signed upload tokens to create time-limited URLs that you can share with your users. Create the signed URL by invoking the createSignedUploadUrl method on the SDK, then pass the returned token to uploadToSignedUrl to complete the upload.

// Create a signed upload URL
const { data } = await supabase.storage.from('bucket_name').createSignedUploadUrl('file_path')
// Upload to the signed URL
const { error } = await supabase.storage
.from('bucket_name')
.uploadToSignedUrl('file_path', data.token, file)
// Create a signed upload URL
final response = await supabase.storage.from('bucket_name').createSignedUploadUrl('file_path');
// Upload to the signed URL
await supabase.storage.from('bucket_name').uploadToSignedUrl('file_path', response.token, file);
// Create a signed upload URL
let signedUrl = try await supabase.storage.from("bucket_name").createSignedUploadURL(path: "file_path")
// Upload to the signed URL
try await supabase.storage.from("bucket_name")
.uploadToSignedURL(path: "file_path", token: signedUrl.token, data: file)
// Create a signed upload URL
val signedUrl = supabase.storage.from("bucket_name").createSignedUploadUrl("file_path")
// Upload to the signed URL
supabase.storage.from("bucket_name").uploadToSignedUrl("file_path", signedUrl.token, bytes)
# Create a signed upload URL
response = supabase.storage.from_('bucket_name').create_signed_upload_url('file_path')
# Upload to the signed URL
with open('local_file_path', 'rb') as f:
supabase.storage.from_('bucket_name').upload_to_signed_url(
path='file_path',
token=response.token,
file=f,
)
// Create a signed upload URL
var signedUrl = await supabase.Storage.From("bucket_name").CreateUploadSignedUrl("file_path");
// Upload to the signed URL
await supabase.Storage.From("bucket_name").UploadToSignedUrl("local_file_path", signedUrl);
# Create a signed upload URL
curl -X POST "https://{your_project_ref}.supabase.co/storage/v1/object/upload/sign/{bucket_name}/{file_path}" \
-H "apikey: {your_anon_key}" \
-H "Authorization: Bearer {your_jwt_token}"
# Upload to the signed URL, using the token returned above
curl -X PUT "https://{your_project_ref}.supabase.co/storage/v1/object/upload/sign/{bucket_name}/{file_path}?token={token}" \
--data-binary "@/local/path/to/your/file.ext"

Revoke signed URLs

You can't revoke individual signed URLs. To revoke all signed URLs, rotate your project's URL signing key, and then revoke the previous key. For more information, see URL Signing Keys.