File Uploads
Add S3 file uploads to your SST app.
Overview
To allow your users to upload files to your app you'll need to:
- Create an S3 bucket
- Bind your frontend to the bucket
- Generate a presigned URL for the upload
- Upload the file by making a request to the URL
Let's look at this in detail!
Get started
Start by creating a new SST + Next.js app by running the following command in your terminal. We are using Next.js for this example but you can use your favorite frontend.
npx create-sst@latest --template standard/nextjs
Add an S3 bucket
Next, add an S3 bucket to your stacks. This will allow you to store the uploaded files.
const bucket = new Bucket(stack, "public");
Make sure to import the Bucket construct.
- import { StackContext, NextjsSite } from "sst/constructs";
+ import { Bucket, StackContext, NextjsSite } from "sst/constructs";
Bind the bucket
After adding the bucket, bind your Next.js app to it.
const site = new NextjsSite(stack, "site", {
path: "packages/web",
+ bind: [bucket],
});
This allows Next.js app to access our S3 bucket.
Generate a presigned URL
When a user uploads a file, we want to generate a presigned URL that allows them to upload the file directly to S3. We will do this using the AWS SDK.
export async function getServerSideProps() {
const command = new PutObjectCommand({
ACL: "public-read",
Key: crypto.randomUUID(),
Bucket: Bucket.public.bucketName,
});
const url = await getSignedUrl(new S3Client({}), command);
return { props: { url } };
}
The above generates a presigned URL that allows public-read access to the uploaded files. You can change the ACL to private or authenticated-read if you prefer.
Add the imports
Import the required packages.
import crypto from "crypto";
import { Bucket } from "sst/node/bucket";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
Make sure to install them as well.
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
Create an upload form
Finally, we can create a form that allows users to upload a file:
export default function Home({ url }: { url: string }) {
return (
<main>
<form
onSubmit={async (e) => {
e.preventDefault();
const file = (e.target as HTMLFormElement).file.files?.[0]!;
const image = await fetch(url, {
body: file,
method: "PUT",
headers: {
"Content-Type": file.type,
"Content-Disposition": `attachment; filename="${file.name}"`,
},
});
window.location.href = image.url.split("?")[0];
}}
>
<input name="file" type="file" accept="image/png, image/jpeg" />
<button type="submit">Upload</button>
</form>
</main>
);
}
This form uploads the file directly to S3 and redirects to the file's URL.
That's it! You now know how to add file uploads with S3 to your SST app.

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.
