S3 presigned upload URL

Simple method to generate a presigned upload URL for Amazon S3 or compatible storage services, allowing client-side uploads without the necessity of routing the file through an additional backend service.

This method needs to be called on the backend. The resulting endpoint URL can then be used client-side to upload the file. You may use the useXmlHttpUpload() hook to upload a file to the presigned URL.

Assuming the required connection details are set as environment variables:

  • S3_ENDPOINT
  • S3_REGION
  • S3_ACCESS_KEY_ID
  • S3_ACCESS_KEY_SECRET
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

export const s3Client = new S3Client({
  endpoint: env.S3_ENDPOINT,
  forcePathStyle: false,
  region: env.S3_REGION,
  credentials: {
    accessKeyId: env.S3_ACCESS_KEY_ID,
    secretAccessKey: env.S3_ACCESS_KEY_SECRET,
  },
});

export async function createPresignedUploadUrl(
  filename: string,
  bucket: string
) {
  const command = new PutObjectCommand({
    Bucket: bucket,
    Key: filename,
  });

  return getSignedUrl(s3Client, command, { expiresIn: 3600 });
}