OffloadKit manages media offload, delivery and recovery with Cloudflare R2, AWS S3 and DigitalOcean Spaces. A Google Cloud Storage HMAC adapter is also available; configure its interoperability credentials and delivery URL separately.
Uploads can be offloaded during upload or processed through the background queue. Failed transfers retain local copies for retry. For public media with retained local files, delivery falls back locally when a storage check confirms the remote object is missing. Storage errors are not treated as proof that an object is missing; cloud-only media requires repair or restoration if its remote copy is lost.
Features
<picture> output with AVIF and WebP sources.CDN presets
Cloudflare setup automatically discovers an active custom domain or enabled R2.dev delivery URL. If neither is available, you can opt in to public R2.dev delivery or configure a custom domain. Existing delivery URLs are preserved when reconnecting the same bucket.
Delivery settings include CloudFront, Bunny CDN, Fastly, KeyCDN, Gcore, Cloudflare and Azure Front Door presets, plus a custom URL / direct bucket option. Each preset provides a URL example and setup guidance. Configure the CDN origin and HTTPS in its dashboard, enter your complete delivery URL, save, then run Test Connection. Selecting a preset preserves the existing URL and does not provision a CDN or enable CDN-specific cache purging.
Legacy URL rewriting covers the full rendered template on WordPress 6.9 and later. On WordPress 6.8, it covers post content and standard WordPress media hooks.
Credentials
Credentials can be defined in wp-config.php instead of the database, which is the recommended production setup:
define( 'R2CLOUDER_PROVIDER', 'r2' ); // r2, s3, spaces or gcs
define( 'R2CLOUDER_ACCOUNT_ID', '...' ); // r2 only
define( 'R2CLOUDER_REGION', 'us-east-1' ); // AWS region or Spaces datacenter
define( 'R2CLOUDER_ACCESS_KEY', '...' );
define( 'R2CLOUDER_SECRET_KEY', '...' );
define( 'R2CLOUDER_BUCKET', '...' );
define( 'R2CLOUDER_PUBLIC_URL', 'https://cdn.example.com' );
define( 'R2CLOUDER_CF_PROVISIONING_TOKEN', '...' );
define( 'R2CLOUDER_CF_API_TOKEN', '...' );
The recommended setup accepts one Cloudflare token with Workers R2 Storage Write. OffloadKit can create or select the bucket, derive the S3 credentials, and configure delivery. Zone Read is optional for automatic custom-domain discovery; Cache Purge is optional for purge-by-URL. Manual bucket-scoped credentials remain available under Advanced.
DigitalOcean Spaces uses the selected datacenter endpoint (for example https://nyc3.digitaloceanspaces.com). Google Cloud Storage uses https://storage.googleapis.com with HMAC interoperability keys, not service-account JSON credentials. Configure a public delivery URL or CDN separately. Managed bucket migration supports R2 and AWS S3 only.
Cloudflare® and Cloudflare R2 are trademarks of Cloudflare, Inc. This plugin is not affiliated with, endorsed by, or sponsored by Cloudflare, Inc.
DigitalOcean onboarding can create a new Standard Storage bucket using a Full access Spaces key, or connect an existing bucket. New buckets are private unless you explicitly allow public object reads. OffloadKit prefills the new bucket delivery URL; CDN configuration remains in DigitalOcean. Existing bucket policies are not modified.
This plugin connects to the storage provider you select after you configure credentials for your own account. CDN preset examples are placeholders. The plugin bundles its own admin assets. Cloudflare tokens can also be supplied for optional setup and cache purging. Deactivating the plugin stops its background requests; previously published media URLs may still be requested by visitors’ browsers.
1. Cloudflare R2 storage API — https://<your-account-id>.r2.cloudflarestorage.com
Used to store and manage your media files. The plugin sends the contents of the media files you upload, their file names and MIME types, and an AWS Signature Version 4 request signature derived from the R2 access key you configure. Requests are made when a file is offloaded, verified, listed or deleted, and during the connection test on the settings screen. No visitor data and no personal data beyond what your own media files contain is transmitted.
1b. AWS S3 storage API — https://<bucket>.s3.<region>.amazonaws.com
Used only when you choose AWS S3 as the provider. The same data is sent as for R2: media file contents, file names, MIME types and an AWS Signature Version 4 request signature derived from the IAM access key you configure.
AWS terms: https://aws.amazon.com/service-terms/
AWS privacy notice: https://aws.amazon.com/privacy/
Additional storage providers
DigitalOcean Spaces requests go to https://.digitaloceanspaces.com. Google Cloud Storage requests go to https://storage.googleapis.com. Only the selected provider receives media contents, file names, MIME types and signed storage requests, during offloading, verification, listing, deletion and connection tests.
DigitalOcean terms: https://www.digitalocean.com/legal/terms-of-service-agreement
DigitalOcean privacy: https://www.digitalocean.com/legal/privacy-policy
Google Cloud terms: https://cloud.google.com/terms
Google privacy: https://policies.google.com/privacy
1c. Bucket migration services — https://api.cloudflare.com and https://datasync.<region>.amazonaws.com
Used only when you start a bucket migration. S3 to R2 migrations send the source bucket name, region and access keys, and the target bucket and keys, to Cloudflare Super Slurper. R2 to S3 migrations send the R2 endpoint, bucket and access keys to AWS DataSync, signed with the target IAM keys. Both services copy the files themselves; the plugin sends no file contents.
Migration status checks and cancellation also contact the selected migration service. Provider storage and migration charges may apply. The Cloudflare and AWS terms and privacy links in this section apply to these services too.
2. Your public delivery domain — the value you set as the public URL
Used to serve offloaded files to visitors, and fetched during connection tests to confirm the domain serves the bucket. Visitors’ browsers request these URLs directly; their IP address and user agent reach your selected delivery provider.
3. Cloudflare API — https://api.cloudflare.com
Used during the optional one-token setup flow, when cache purging is enabled, or when you choose Connect Domain or Check Status. During setup, the plugin sends the account ID, desired bucket name and location, delivery choice, custom domain and Zone ID when applicable, and the Cloudflare API token needed to authorize those operations. For cache purging, it sends media URLs after an attachment is updated, re-offloaded, or deleted. Manual setup can avoid the provisioning flow entirely.
Cloudflare terms of service: https://www.cloudflare.com/terms/
Cloudflare privacy policy: https://www.cloudflare.com/privacypolicy/