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
- Sign in to Cloudflare and open Storage & Databases → R2 Object Storage
- Click Create bucket
- Give it a clear permanent name (e.g.
bloggfast-storage) - Set Location to Automatic and Default Storage Class to Standard
- 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
- Still on the R2 page, click Manage next to API tokens
- Create a new Account API Token
- Grant Admin Read & Write access; leave other settings at defaults
- Copy the Access Key ID →
R2_ACCESS_KEY_ID - Copy the Secret Access Key →
R2_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
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=100Swapping 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.