Skip to main content
General

Storage

Understand the image storage integration that ships with the Pro Next.js Drizzle starter kit.

Open MarkdownFull AI corpusFeedback

The starter kit includes an S3-compatible image storage integration for user avatars and organization logos. It is configured for Cloudflare R2 and can be adapted to another provider that supports the S3 API.

What ships

  • lib/storage/s3.ts creates an S3 client and presigns PutObject and GetObject commands.
  • trpc/routers/storage/index.ts exposes an authenticated storage.signedUploadUrl mutation for the configured images bucket.
  • app/storage/[...path]/route.ts exposes a public image redirect route.
  • hooks/use-storage.tsx converts a stored image key into the public route URL.
  • Avatar and organization logo components crop an image, upload it directly and save its key through Better Auth.

The included flow is intended for display images such as avatars and logos. The generated UUID-based keys make accidental discovery less likely, but an unguessable key is not authorization.

What does not ship

The repositories do not include:

  • A file metadata table
  • User or organization ownership checks for storage objects
  • Private download, listing or deletion procedures
  • File quota enforcement, malware scanning or audit logs
  • Automatic object deletion when an avatar or logo is removed
  • Server-enforced file size or MIME type validation

Add those controls before using the storage integration for invoices, exports, identity documents or other private files. See Access Files for the required design changes.

Environment variables

.env
S3_ACCESS_KEY_ID="your-access-key"
S3_SECRET_ACCESS_KEY="your-secret-key"
S3_ENDPOINT="https://your-s3-endpoint"
S3_REGION="auto"
NEXT_PUBLIC_IMAGES_BUCKET_NAME="your-images-bucket"

NEXT_PUBLIC_IMAGES_BUCKET_NAME is public configuration. Keep the access key and secret key server-only.