Skip to main content
ShipFree includes built-in integration with Cloudflare R2 for object storage, providing S3-compatible storage without egress fees. The storage client supports both public and private buckets with signed URL generation.

Why Cloudflare R2?

Zero Egress Fees

No charges for data transfer out

S3 Compatible

Works with existing S3 tools and libraries

Global Performance

Cloudflare’s global network for fast access

Cost Effective

Significantly cheaper than traditional cloud storage

Storage Client

The storage client is implemented in src/lib/storage.ts:
src/lib/storage.ts

Configuration

1

Create R2 Buckets

Create public and private buckets in your Cloudflare dashboard:
  • Public bucket: For publicly accessible files (images, assets)
  • Private bucket: For user uploads and sensitive files
2

Generate API Tokens

Create an R2 API token with read/write permissions.
3

Set Environment Variables

.env
You can get your Cloudflare Account ID from the R2 dashboard URL: https://dash.cloudflare.com/{account_id}/r2

Uploading Files

Upload from File

Upload from Base64

src/lib/storage.ts

Upload from URL

src/lib/storage.ts
The storage client uses wsrv.nl for on-the-fly image resizing when uploading from URLs.

Bucket Types

Public Bucket

Use for publicly accessible files:
Files in the public bucket can be accessed directly via their URL without authentication.

Private Bucket

Use for sensitive user data:
Files in private buckets cannot be accessed directly. Use signed URLs for temporary access.

Signed URLs

Generate temporary URLs for secure file access:

Upload URLs

Download URLs

Deleting Files

Server Action Example

Implement file upload in a Server Action:
src/app/actions/upload.ts

Client Component Example

src/components/avatar-upload.tsx

API Route Example

src/app/api/upload/route.ts

Utility Functions

The storage module includes helpful utilities:

Check if URL is Stored

src/lib/storage.ts

Check if Image is Not Hosted

src/lib/storage.ts

Image Resizing

When uploading from URLs, you can resize images on the fly:
The storage client uses a proxy service for image transformation. The original image is fetched, resized, and then uploaded to R2.

Error Handling

Custom Headers

Add custom headers to uploads:

Best Practices

Use Descriptive Keys

Use clear, hierarchical paths like avatars/user-123.jpg

Set Content Types

Always specify the correct MIME type for uploads

Validate File Sizes

Check file sizes before uploading to prevent abuse

Clean Up Unused Files

Implement cleanup jobs to remove orphaned files

Environment Variables

.env
You can set up a custom domain for your R2 bucket in Cloudflare to use branded URLs instead of the default r2.dev domain.

Further Reading

Cloudflare R2 Docs

Official Cloudflare R2 documentation

S3 API Compatibility

Learn about S3-compatible API features

Custom Domains

Set up custom domains for R2 buckets

Access Control

Managing access tokens and permissions