Amazon S3
Configuration, CORS, and bucket policies for AWS S3.
Amazon S3 supports presigned POST and PUT uploads, object ACLs, and multipart uploads.
Bucket CORS configuration
Because the browser uploads directly to your S3 bucket, configure a bucket CORS policy:
[
{
"AllowedOrigins": ["https://your-app.example", "http://localhost:3000"],
"AllowedMethods": ["GET", "PUT", "POST", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag", "Content-Type"],
"MaxAgeSeconds": 3000
}
]Server configuration
import { S3Client } from "@aws-sdk/client-s3";
import { dimahS3, route } from "@dimah-s3/server";
export const awsS3 = new S3Client({
region: process.env.S3_REGION!,
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY_ID!,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
},
});
export const s3 = dimahS3({
client: awsS3,
bucket: process.env.S3_BUCKET!,
routes: {
avatar: route({
upload: {
fileTypes: ["image/*"],
maxFileSize: 2 * 1024 * 1024,
},
}),
},
});Frequently asked questions
If your bucket allows object ACLs, set upload: { acl: "public-read" } on the
route:
avatar: route({
upload: {
acl: "public-read",
fileTypes: ["image/*"],
maxFileSize: 2 * 1024 * 1024,
},
});New S3 buckets commonly use Bucket owner enforced Object Ownership, which disables ACLs. For those buckets, keep uploads private and grant public reads through a bucket policy or CDN instead.
First, make sure AllowedOrigins exactly matches the browser origin, including
the scheme and development port. Then allow the upload method and request
headers used by the presigned request. ExposeHeaders does not fix a 403, but
it must include ETag when the browser needs to read multipart responses.