CloudflareAssets by NB Communication

Extends Pagefile to use Cloudflare Images, Stream and R2 storage to serve files.

Cloudflare Assets

Extends Pagefile to use Cloudflare Images, Stream and R2 storage to serve files.


The main purpose of this module is to allow ProcessWire to be used in an auto-scaling multi-instance environment. By serving file assets from Cloudflare, it is not necessary to have all file assets copied to all instances and we also get the benefits of serving assets from a CDN.

How it works

When a Pagefile is added in the admin or via the API, it is uploaded to Cloudflare's R2 storage service. Additionally, if the file is an image, it is uploaded to Cloudflare Images, and if the file is a video it is uploaded to Cloudflare Stream. When a URL for the Pagefile is requested e.g. $pagefile->url(), the appropriate Cloudflare URL is returned.

As ProcessWire's admin still requires the file to be available locally, in a multi-instance setup if a file is not available it is downloaded from the 'master' copy in R2. Conversely, if an uploaded file is on the local filesystem, but not in Cloudflare's services, it will attempt to add it. This should allow the module to function where files and images have already been uploaded at the time of install.


  1. Download the zip file at Github or clone the repo into your site/modules directory.
  2. If you downloaded the zip file, extract it in your sites/modules directory.
  3. In your admin, go to Modules > Refresh, then Modules > New, then click on the Install button for this module.

ProcessWire >= 3.0.210 and PHP >= 8.1.0 are required to use this module.


To configure this module, go to Modules > Configure > CloudflareAssets. In another tab, open your Cloudflare dashboard.

The following settings are used for more than one service:

  • Account ID: You should find this at the top of right sidebar on any of the main screens for R2 / Stream / Images.
  • Access Token: This is used for API access for Stream and Images. See Creating an API Token below.
  • Custom domain: This must be a domain managed and served by Cloudflare. See Creating a custom domain below.

Creating an API Token

To create an API token:

  • Navigate to My Profile > API Tokens.
  • Click Create Token.
  • Click Use template for Read and write to Cloudflare Stream and Images.
  • Remove Read access for Account Analytics.
  • In Account Resources select the account you will be using - it does not need access to all accounts.
  • If you have a static IP or IP range and wish to limit access by this, enter it in Client IP Address Filtering.
  • If you wish to time limit the token, set a range in TTL (not recommended for the purposes of this module).
  • Click Continue to summary.

Creating a custom domain

Coming soon: These instructions will be written in the near future (May 2023).

Connecting your custom domain

Your custom domain needs to be manually connected to your bucket.

  • In your bucket dashboard go to Settings > Public access > Custom Domains.
  • Click Connect Domain.
  • Add the domain you wish to connect and click Continue.
  • Allow Cloudflare to add the CNAME record by clicking Connect domain.


This information can be found in the R2 area of your Cloudflare account:

  • Bucket: The bucket name cannot be changed once entered. Please make sure you enter the bucket name you want to use. If the bucket does not already exist, it will be created.
  • Access Key ID
  • Secret Access Key

To get your Access Key ID and Secret Access Key:

  • Click on Manage R2 API Tokens at the top of the right sidebar.
  • Click Create API Token.
  • Give the token a name (e.g. ProcessWire)
  • Set its permissions to Edit
  • Add a TTL if your wish (not recommended for the purposes of this module)
  • If you have a static IP or IP range and wish to limit access by this, enter it in Client IP Address Filtering.
  • Click Create API Token.
  • Copy the Access Key ID and Secret Access Key to the module configuration.
  • Click Finish.


  • Customer subdomain: This can be found in the right sidebar on the Stream dashboard.
  • Allowed origins: This defaults to $config->httpHosts. If you need to add more allowed origins, enter them on a new line.


  • Account hash: This can be found in the right sidebar on the Images dashboard.
  • Use Image Delivery URL: If enabled, Cloudflare's is used to server image instead of the custom domain.

Only Uploads?

If this is enabled, assets will continue to be uploaded to Cloudflare if authorised, but will be served by the local filesystem. It switches off the Pagefile::url(), Pagefile::httpUrl() and Pageimage::size() hooks. If you encounter a problem with your Cloudflare setup, this option allows you to revert to the default without completely removing the integration.


Once correctly configured, you shouldn't need to use the module at all; all url() and httpUrl() calls will be replaced by the appropriate URL from Cloudflare.

To override the Cloudflare URL, call getLocal on the Pagefile prior to calling url() or httpUrl():

$url = $pagefile->getLocal->url;

Notes on Image Size Limitations


  • Maximum image dimension is 12,000 pixels.
  • Maximum image area is limited to 100 megapixels (for example, 10,000×10,000 pixels).
  • Image metadata is limited to 1024 bytes.
  • Images have a 10 megabyte (MB) size limit.
  • Animated GIFs, including all frames, are limited to 100 megapixels (MP).

Please ensure you configure your image fields so they do not exceed these limits.

Cloudflare Documentation


This project is licensed under the Mozilla Public License Version 2.0.

Install and use modules at your own risk. Always have a site and database backup before installing new modules.

Twitter updates

    Error retrieving Twitter status

Latest news

  • ProcessWire Weekly #473
    In the 473rd issue of ProcessWire Weekly we'll check out latest core updates, introduce new third party module called Template Fragment Controller, and more. Read on! / 3 June 2023
  • A look at the new Page Edit Restore module
    The new Page Edit Restore module helps to prevent page edits in the admin from getting lost when the user’s session is lost. This post covers it in detail.
    Blog / 12 May 2023
  • Subscribe to weekly ProcessWire news

“We chose ProcessWire because of its excellent architecture, modular extensibility and the internal API. The CMS offers the necessary flexibility and performance for such a complex website like ProcessWire offers options that are only available for larger systems, such as Drupal, and allows a much slimmer development process.” —xport communication GmbH