Cloudflare R2 Storage

Create an R2 bucket and wire it up for cover images, AI-generated images, and skills.

Last updated:

What R2 stores in BloggFast

  • Article cover images (uploaded manually or generated by AI)
  • Per-user Skill files — small assets the AI generator uses as context
  • Other attachments referenced from articles

Uploads use the AWS S3 SDK (@aws-sdk/client-s3) pointed at R2's S3-compatible endpoint.

Create the bucket

  1. Sign in to Cloudflare and open Storage & Databases → R2 Object Storage
  2. Click Create bucket
  3. Give it a clear permanent name (e.g. bloggfast-storage)
  4. Set Location to Automatic and Default Storage Class to Standard
  5. Click Create bucket

From the R2 Overview, scroll to Account details and copy the Account ID and S3 API endpoint — these go into CLOUDFLARE_ACCOUNT_ID and R2_ENDPOINT.

Create an account API token

  1. Still on the R2 page, click Manage next to API tokens
  2. Create a new Account API Token
  3. Grant Admin Read & Write access; leave other settings at defaults
  4. Copy the Access Key IDR2_ACCESS_KEY_ID
  5. Copy the Secret Access KeyR2_SECRET_ACCESS_KEY

Enable the Public Development URL

Open the bucket's Settings, find the Public Development URL section, and toggle it on. Cloudflare will generate a unique URL like https://pub-xxx.r2.dev. Copy it into R2_PUBLIC_DEVELOPMENT_URL.

Environment variables

.env
CLOUDFLARE_ACCOUNT_ID=your_cloudflare_account_id
R2_BUCKET_NAME=bloggfast-storage
R2_ENDPOINT=https://your_account_id.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID=your_r2_access_key_id
R2_SECRET_ACCESS_KEY=your_r2_secret_access_key
R2_PUBLIC_BASE_URL=                         # leave empty for now
R2_PUBLIC_DEVELOPMENT_URL=https://pub-xxx.r2.dev
NEXT_PUBLIC_MAX_UPLOAD_MB=100

Swapping in a custom domain later

Once you have a production domain, attach it to the bucket under Settings → Custom Domains, then set R2_PUBLIC_BASE_URL to the custom URL. The app prefers R2_PUBLIC_BASE_URL when it's populated and falls back to R2_PUBLIC_DEVELOPMENT_URL.