Connect Cloudflare R2 to WordPress
To offload WordPress media to Cloudflare R2, install Offloft, create an R2 bucket and an API token limited to that bucket, then connect your own domain so visitors can load files. Offloft tests the connection and public delivery before it serves anything from the cloud.
What you'll need
- A Cloudflare account
- A WordPress admin login
- Offloft installed (WordPress 6.5 or later and PHP 8.1 or later with the cURL extension)
- 1
Create the bucket
In the Cloudflare dashboard, go to Storage & databases > R2 > Overview and select Create bucket.
Name: lowercase letters, numbers and hyphens, 3 to 63 characters, not starting or ending with a hyphen.
Location: leave it on Automatic, or pick the region closest to most of your visitors.
Choose Specify jurisdiction only if your files must stay in the European Union, FedRAMP or United States jurisdiction. It cannot be changed later, and you must pick the same jurisdiction in Offloft.
Bucket namemy-site-media
- 2
Create an API token for Offloft
On the R2 Overview page, under Account Details, select Manage next to API Tokens.
Select Create Account API token. An account token keeps working if the person who made it leaves your Cloudflare account; a User API token does not.
Permissions: choose Object Read & Write. Offloft never needs Admin permissions.
Under Specify bucket(s), choose Apply to specific buckets only and pick "my-site-media", so the token cannot touch your other buckets.
Select Create API Token. Copy the Access Key ID and the Secret Access Key into Offloft together with your account ID. Cloudflare shows the secret only once.
Account IDyour-account-id
S3 endpoint (Offloft fills this in for you)https://your-account-id.r2.cloudflarestorage.com
- 3
Connect your own domain
R2 buckets are private until you connect a domain. Open the bucket, go to Settings > Custom Domains and select Add.
Enter media.yoursite.com, select Continue, then Connect Domain. The domain must be a zone in this same Cloudflare account.
Wait until the status changes from Initializing to Active, usually a few minutes.
In Offloft, use https://media.yoursite.com as the delivery address.
Domainmedia.yoursite.com
Delivery addresshttps://media.yoursite.com
- 4
Or: turn on the r2.dev address for testingOptional
Without a domain you can try things out with Cloudflare's r2.dev address. It is rate-limited and not cached, so do not use it for a live site.
Open the bucket, go to Settings > Public Development URL and select Enable. Type "allow" to confirm.
Copy the address it shows (https://pub-….r2.dev) into Offloft as the delivery address.
- 5
Allow your site to read files (CORS)Optional
This step is optional. Images on your pages load without it. You need it only when your site's own scripts read files from storage, for example image editors, web fonts or 3D viewers. The rule below lets only your site read files, and only read them.
Open the bucket, go to Settings > CORS Policy, select Add CORS policy, choose the JSON tab and paste the rule.
CORS policy[ { "AllowedOrigins": ["https://yoursite.com"], "AllowedMethods": ["GET", "HEAD"], "AllowedHeaders": ["*"], "MaxAgeSeconds": 3600 } ] - 6
Check Cloudflare rules on your domainOptional
Your domain runs through Cloudflare, so its rules apply to your files too. If the delivery check says files come back changed or with the wrong type, look at the rules on the zone for media.yoursite.com:
Rules > Overview (Transform Rules, Cache Rules, Redirect Rules), Workers routes, and Speed settings that rewrite content.
A cache rule that caches everything on media.yoursite.com is fine and makes files faster.
- 7
Run the connection test and the delivery check
In Offloft, paste your values and run the connection test. It checks your credentials, finds the bucket, uploads a test file, reads it back and deletes it. The delivery check then loads a small test image from your public address. Offloft serves nothing from the cloud until both pass.
Permissions Offloft needs
An Account API token with Object Read & Write, applied to this bucket only. Offloft never needs Admin permissions.
Serving your files
R2 buckets are private until you connect a domain. Use your own domain, which must be a zone in the same Cloudflare account. Cloudflare's r2.dev address is for testing only: it is rate-limited and not cached. The delivery check loads a small test image from whichever address you enter.
If the test fails
Cloudflare R2 questions
Should I use a custom domain or the r2.dev address?
A custom domain for a live site. Cloudflare's r2.dev address is rate-limited and not cached, so keep it for testing.
Which kind of API token should I create?
An Account API token. It keeps working if the person who made it leaves your Cloudflare account; a User API token does not.
What if I chose a jurisdiction for my bucket?
Pick the same jurisdiction in Offloft. A jurisdiction cannot be changed after the bucket is created.
Do I need the CORS step?
Only when your site's own scripts read files from storage, for example image editors, web fonts or 3D viewers. Images on your pages load without it.
Ready to connect your bucket?
Install Offloft free. Nothing moves until the connection test passes.