dimah-s3v1.5.4
Providers

Cloudflare R2

PUT uploads, endpoint configuration, and CORS for Cloudflare R2.

Cloudflare R2 is compatible with S3 APIs with two key differences: it requires Presigned PUT (it does not support Presigned POST), and it ignores object ACLs.

Configure upload method

Set upload: { method: "PUT" }:

lib/s3.ts
import { S3Client } from "@aws-sdk/client-s3";
import { dimahS3, route } from "@dimah-s3/server";

export const awsS3 = new S3Client({
  region: "auto",
  endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID!,
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
  },
});

export const s3 = dimahS3({
  client: awsS3,
  bucket: process.env.R2_BUCKET!,
  routes: {
    avatar: route({
      upload: {
        method: "PUT", // Required for Cloudflare R2
        fileTypes: ["image/*"],
        maxFileSize: 2 * 1024 * 1024,
      },
    }),
  },
});

Bucket CORS policy

Add a CORS rule in the Cloudflare R2 dashboard for your frontend domain:

[
  {
    "AllowedOrigins": ["https://your-app.example"],
    "AllowedMethods": ["GET", "PUT", "HEAD"],
    "AllowedHeaders": ["*"],
    "ExposeHeaders": ["ETag", "Content-Type"],
    "MaxAgeSeconds": 3000
  }
]

Frequently asked questions

On this page