generatePresignedUploadUrl
Generate a presigned URL for secure file uploads to S3-compatible storage
Backend Implementation Required
This function must be implemented on your backend server and cannot be safely exposed to the frontend. The function handles sensitive S3 credentials and should only be called from your server-side code.
CORS Configuration Required
You must configure CORS settings on your S3 bucket or storage provider to allow your frontend domain to upload files using the generated presigned URLs. Without proper CORS configuration, uploads will fail with cross-origin errors.
Usage
import { generatePresignedUploadUrl } from '@/lib/generate-presigned-upload-url';
const { uploadUrl, key, fileUrl } = await generatePresignedUploadUrl({
fileName: file.name,
contentLength: file.size,
expiresIn: 3600
});Installation
pnpm dlx shadcn@latest add https://utilcn.dev/r/generate-presigned-upload-url.jsonbunx --bun shadcn@latest add https://utilcn.dev/r/generate-presigned-upload-url.jsonnpx shadcn@latest add https://utilcn.dev/r/generate-presigned-upload-url.jsonyarn shadcn@latest add https://utilcn.dev/r/generate-presigned-upload-url.jsonParameters
| Parameter | Type | Description | Default |
|---|---|---|---|
fileName | string | The original filename with extension | - |
contentLength | number | The size of the file in bytes | - |
expiresIn | number | URL expiration time in seconds | 3600 |
Returns
An object containing:
uploadUrl- The presigned URL for uploading the filekey- The unique key/path where the file will be storedfileUrl- The public URL where the file will be accessible after upload
Environment Variables
This function requires the following environment variables:
S3_REGION=your-region
S3_ENDPOINT=your-s3-endpoint
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
S3_BUCKET_NAME=your-bucket-name
S3_PUBLIC_URL=your-public-urlSupported File Types
The function automatically detects content types for common file extensions:
- Images: jpg, jpeg, png, gif, webp, svg
- Documents: pdf, doc, docx
- Other: json, txt
- Default: application/octet-stream for unknown types
File Size Limits
- Maximum file size: 10MB (customizeable)
- Files exceeding this limit will throw an error
Dependencies
@aws-sdk/client-s3@aws-sdk/s3-request-presigner
Implementation
import { PutObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { getS3Client } from '@/lib/s3-client';
const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB
type PresignedUrlInput = {
fileName: string;
expiresIn?: number;
contentLength: number;
};
export async function generatePresignedUploadUrl({
fileName,
expiresIn = 3600,
contentLength,
}: PresignedUrlInput) {
if (contentLength > MAX_FILE_SIZE_BYTES) {
throw new Error('File size exceeds maximum allowed limit');
}
try {
const fileExt = fileName.split('.').pop()?.toLowerCase() ?? '';
const uniqueId = Date.now().toString();
const key = fileExt ? `${uniqueId}.${fileExt}` : uniqueId;
const contentType = getContentType(fileExt);
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET_NAME,
Key: key,
ContentType: contentType,
ContentLength: contentLength,
});
const uploadUrl = await getSignedUrl(getS3Client(), command, { expiresIn });
const fileUrl = `${process.env.S3_PUBLIC_URL}/${key}`;
return { uploadUrl, key, fileUrl };
} catch (err) {
console.error({ err }, 'Failed to generate presigned upload URL');
throw new Error('Failed to generate upload URL');
}
}
function getContentType(extension: string): string {
switch (extension) {
// Images
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'gif':
return 'image/gif';
case 'webp':
return 'image/webp';
case 'svg':
return 'image/svg+xml';
// Documents
case 'pdf':
return 'application/pdf';
case 'doc':
return 'application/msword';
case 'docx':
return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
// Other common types
case 'json':
return 'application/json';
case 'txt':
return 'text/plain';
default:
return 'application/octet-stream';
}
}Frontend Integration
uploadFile
Generate presigned URLs for secure file uploads to cloud storage