Uploading files
Learn how to upload files in your supastarter application.
Before you start uploading files, make sure to setup your storage.
You also want to make sure that you have the bucket created that you want to upload files to.
For this example we are going to upload a PDF file to a bucket called documents, that we assume you have already created in your storage provider.
Make sure to disable public access to all your buckets as we will care about access control in the API layer of the application.
Add the bucket name to the config
For easy reusability, we recommend adding the bucket name to the config.
export const config: StorageConfig = {
bucketNames: {
avatars: process.env.NEXT_PUBLIC_AVATARS_BUCKET_NAME ?? "avatars",
documents: "documents",
},
};Prepare upload endpoint
supastarter uses presigned URLs to upload files to your storage provider.
So what we need to do first is to extend the upload API route to be able to upload files to the documents bucket.
The upload route handler checks the bucket name and only allows uploads to whitelisted buckets. Add a check for the documents bucket:
// only allow uploads to the documents bucket
if (bucket === config.storage.bucketNames.documents) {
const signedUrl = await getSignedUploadUrl(path, { bucket });
return c.json({ signedUrl });
}This route will now allow authenticated users to get a signed upload URL for the documents bucket.
If you want to only allow uploading to specific paths or check for specific file types, you can add additional validation.
Upload files from the UI
In order to upload files from the UI, use your preferred method to select a file (like a file input or a dropzone component). Then you need to execute the following steps:
- Get a signed upload URL for the file you want to upload.
- Upload the file to the signed URL.
- Store the file url to your database to be able to use the file later.
<script setup lang="ts">
const uploading = ref(false);
const { user } = useSession();
const uploadFile = async (file: File) => {
if (!user.value) return;
uploading.value = true;
try {
const path = `${user.value.id}/${crypto.randomUUID()}.pdf`;
const { signedUrl } = await getSignedUploadUrl(path, {
bucket: config.storage.bucketNames.documents,
});
const response = await fetch(signedUrl, {
method: "PUT",
body: file,
headers: {
"Content-Type": file.type,
},
});
if (!response.ok) {
throw new Error("Failed to upload document");
}
// TODO: store the file path to the database
} catch (e) {
// TODO: handle error
} finally {
uploading.value = false;
}
};
</script>Now your users can upload files to the documents bucket.
In the next step you can learn how to access the uploaded files.