Skip to content

Updating visuals

If you see any images containing outdated UI, please bear with us.

We are updating all content as quickly as possible to mirror our new UI.

Cloudflare R2 storage ​

Cloudflare R2 is a storage service for files (images, PDFs, uploads). You can connect it to WeWeb so your project keeps its Public and Private files in your own Cloudflare account instead of in WeWeb Storage.

R2 has its own provider in WeWeb. You give WeWeb your account ID and your R2 keys, and it fills in the R2 address and region for you.

What you need before you start ​

  • A bucket for your private files. If your app also needs files that anyone can open with a link, a second bucket for your public files. The bucket is the only thing that separates private from public, so you cannot use the same bucket for both. WeWeb refuses two identical bucket names.
  • An R2 API token with Object Read & Write access to those buckets. Creating it gives you an access key ID and a secret access key.
  • Your Cloudflare account ID.
  • For public files only: a public address for your public bucket, either your own domain or the r2.dev address that Cloudflare can turn on.

ONLY STORING PRIVATE FILES?

Leave the public bucket and its URL empty. You only need the private bucket and your keys.

Step 1: create your buckets and your keys in Cloudflare ​

  1. In the Cloudflare dashboard, open R2 object storage and create a bucket for your private files.
  2. If you need public files, create a second bucket for them.
  3. On the R2 Overview page, under Account Details, click Manage next to API Tokens.
  4. Click Create Account API token. Under Permissions, select Object Read & Write. You can limit the token to your buckets.
  5. Create the token, then copy the Access Key ID and the Secret Access Key. Cloudflare only shows the secret once.
  6. Copy your account ID. In the dashboard, press Ctrl + K (Cmd + K on Mac) and search for Copy account ID.

USE THE R2 KEYS, NOT A CLOUDFLARE API TOKEN

WeWeb needs the access key ID and the secret access key of your R2 token. A regular Cloudflare API token does not work in these fields.

Learn more about R2 API tokens in the Cloudflare docs →

Step 2: give your public bucket a public address ​

Skip this step if you only store private files.

R2 does not make a bucket readable by anyone by default, and the address WeWeb uses to send and manage your files cannot serve public links. Give your public bucket a public address, in its Settings in Cloudflare:

  • Your own domain (recommended). Under Custom Domains, click Add, enter a domain you manage in the same Cloudflare account, then click Connect Domain.
  • The r2.dev address. Under Public Development URL, click Enable, type allow to confirm, then copy the address. Cloudflare limits the traffic on this address and only recommends it for testing.

Do this on the public bucket only. Your private bucket must stay without a public address.

Learn more about public buckets in the Cloudflare docs →

Step 3: add the connection in WeWeb ​

  1. Go to the Data & API tab, then open the Integrations subtab.
  2. Open Cloudflare R2 and click Add Connection.
  3. Give it a name in Connection Name.
  4. Choose the environment you are configuring (Editor, Staging or Production), then fill in Account ID, Access Key ID and Secret Access Key.
  5. Repeat for each environment you use, then click Save.

There is no address or region to fill in. WeWeb builds the R2 address from your account ID and uses the region R2 expects.

The Cloudflare R2 connection panel in WeWeb, with the written setup steps expanded and the Account ID, Access Key ID and Secret Access Key fields below

EMPTY ENVIRONMENTS REUSE ANOTHER CONNECTION

If you leave Staging or Production empty, your published app uses the connection of another environment instead: Production uses the Staging one if you filled it in, otherwise the Editor one. To run the bucket checks in an environment, though, it needs its own keys.

Step 4: select Cloudflare R2 as your storage ​

  1. Go to the Data & API tab, then open the Storage subtab. If another provider is already set up, go to Settings and use Switch Storage Provider first.
  2. In Connect your storage, choose Cloudflare R2. If you have not created a connection yet, WeWeb asks for it now, with the same fields as in step 3.
  3. Pick your connection in Connection.
  4. Choose the environment, then fill in Private bucket.
  5. If you created a public bucket, fill in Public bucket (optional) and paste its public address from step 2 in Public bucket URL. WeWeb requires this address as soon as you enter a public bucket.
  6. Click Continue.

To change these settings later, open the Settings tab of the Storage subtab. The Cloudflare R2 Configuration panel shows the same fields, with a Save button.

The Cloudflare R2 Configuration panel in Storage Settings, with the connection, the private bucket, public bucket and Public bucket URL fields, and the Run checks button

Step 5: add the CORS rule to your buckets ​

When you upload a file, your browser sends it straight to R2. R2 refuses it unless the bucket has a CORS rule (a list of the addresses allowed to upload) that lets your app in.

  1. In Settings, below Bucket checks, expand Set up Cloudflare R2.
  2. Under Allow uploads from your app, click Copy CORS rule next to a bucket. The rule is already filled with the address of the editor and the domains of your published app.
  3. In Cloudflare, open that bucket, go to Settings, then under CORS Policy click Add CORS policy.
  4. In the JSON tab, paste the rule and click Save.
  5. Do the same for your other bucket.

If you later publish your app on a new domain, copy the CORS rule again. A domain that is not in the list cannot upload.

Learn more about CORS on R2 in the Cloudflare docs →

Step 6: check your buckets ​

In Settings, click Run checks. WeWeb connects to R2 with your keys, reads the CORS rule of each bucket, then loads an image from your public bucket through its public address.

The results are grouped by bucket, with one line per check:

  • Bucket access shows Connected when WeWeb can reach the bucket with your keys.
  • Browser uploads shows CORS verified when the CORS rule lets your app upload.
  • Public links shows Verified when an image in your public bucket opens with its public address. This line only appears for the public bucket.

Each bucket also gets a badge next to its name in the bucket fields: Unchecked before you run the checks, Ready when nothing is left to fix, Warning when something needs a look, and Blocked when the bucket cannot be used as it is.

When something is missing, the panel tells you what it is. Click Check again after each change you make in Cloudflare.

BROWSER UPLOADS SHOWS NOT VERIFIED

If your keys are not allowed to read the CORS settings of a bucket, the check shows a warning (Browser uploads aren’t verified yet) instead of an error, with the message from Cloudflare under Technical details. Make sure you pasted the CORS rule from step 5, then upload a file from your app to confirm it works.

The public links check needs an image to load. If your public bucket is empty, upload one from the Public tab of the Storage subtab, then run the checks again.

Public file URLs ​

WeWeb builds the URL of a public file from the Public bucket URL you entered and the path of the file. You never have to write that address yourself.

To get the URL of a public file, add the url column to a table view joined on your public files, then bind your Image element (or your link) to it.

The value can be empty, for example when the project has no public bucket, so bind it with a fallback rather than assuming it is always there.

THE FILE UPLOADED BUT THE IMAGE IS BROKEN

This almost always means the public bucket has no public address yet, or that Public bucket URL does not match it. The public links check in Settings tells you when the address does not answer.

Private files ​

Private files are never openable with a plain link. Your app asks for a short-lived signed URL when a user needs to view or download the file, exactly as it does with WeWeb Storage.

Learn more about using files in your app →

Common pitfalls ​

The account ID is refused ​

Account ID only accepts the 32-character ID of your Cloudflare account. If you see Enter your 32-character Cloudflare Account ID., copy the ID again from the Cloudflare dashboard and check that no other text came with it.

Public bucket URL is refused ​

This field needs the public address of your public bucket: your custom domain or its r2.dev address. The address that ends in r2.cloudflarestorage.com (the one WeWeb uses to manage your files) cannot serve public links, so WeWeb refuses it.

Uploads fail in the editor or in your app ​

This is a CORS problem. Copy the CORS rule from Settings again, paste it in both buckets, and check that the domain you upload from is in the list.

Private files are reachable publicly ​

Check that Private bucket and Public bucket (optional) are two different buckets, and that only the public bucket has a custom domain or an r2.dev address.

A file cannot be created at a path that already exists ​

Overwriting is off by default, so uploading to a path already in use fails. Delete the file first, or turn on Replace if exists in your upload action.

Deleting a file directly from the Cloudflare dashboard does not remove it from your project's file list, so that path stays blocked until you delete it from WeWeb too.

Files download instead of opening in the browser ​

A file stored without a type is treated as raw data, and browsers download it instead of displaying it. When your app asks for an upload link with Get file signed upload url, fill in Content Type (for example image/png). When you upload an actual file, for example from a File Upload element, the type travels with the file and there is nothing to do.

Copy URL is greyed out in the Storage panel ​

That action is only available with WeWeb Storage. With Cloudflare R2, get the address from the url column of a table view instead.

Good to know ​

  • Signed links expire, so never treat a signed link as permanent.
  • Your buckets do not need any per-file permission settings. WeWeb never sets them.