Send every rendered image or PDF to a Cloudflare R2 bucket you control.
HTML/CSS to Image connects to Cloudflare R2 through its S3-compatible API. You provide an R2 access key, secret, Cloudflare account ID, and the bucket’s data jurisdiction.
Plan availability
Storage destinations are available on the 10,000 images/month plan or higher. If you’d like to try this on a different plan, email support@htmlcsstoimage.com.
Before you begin
You need:
An existing R2 bucket.
The Cloudflare account ID that owns it.
The bucket’s data jurisdiction, if it was created with one.
An optional key prefix, such as hcti-renders.
Create R2 S3 credentials
In the Cloudflare dashboard, open R2 Object Storage, select Manage API Tokens, and create an account or user API token.
Choose Object Read & Write permission.
Scope the token to the destination bucket when possible.
Create the token.
Copy the Access Key ID and Secret Access Key. Cloudflare shows the secret only once.
Read and write access lets HCTI upload renders and reload an original for a later resize, crop, or format conversion when Disable HCTI Storage is selected. HCTI uses delete access only to clean up connection-test objects; it does not delete rendered images from R2.
Optional folder-like prefix, without leading or trailing slashes
Account ID
Cloudflare account ID
Access key ID
R2 token’s Access Key ID
Secret access key
R2 token’s Secret Access Key
Data jurisdiction
The jurisdiction used when the bucket was created
Choose the R2 data jurisdiction
The setting determines which R2 endpoint HCTI uses:
Dashboard option
Endpoint
Use when
Default
<account-id>.r2.cloudflarestorage.com
The bucket has no jurisdiction restriction. This is also the correct option for a bucket with only a location hint.
European Union
<account-id>.eu.r2.cloudflarestorage.com
The bucket was created in the European Union jurisdiction.
FedRAMP
<account-id>.fedramp.r2.cloudflarestorage.com
The bucket was created in the FedRAMP jurisdiction.
The wrong jurisdiction points HCTI at an endpoint that cannot access the bucket. If you change this setting later, run Test connection again before saving.
Test and save the destination
Click Test connection.
Enable and save the destination after the test succeeds.
Copy the destination id.
The test writes a small object under <key-prefix>/.hcti/connection-tests/. Cleanup is best-effort and does not determine whether the connection passes.
Upload an HCTI image to R2
Pass the destination ID as storage_destination_id when you create an image:
Rendering is lazy. With normal HCTI storage enabled, request the returned image URL to render the image and write both copies. With Disable HCTI Storage selected, send an authenticated PUT request to the returned /v1/store/... URL.
The base object is stored as <key-prefix>/<image-id>.png, or .pdf when the request uses pdf_options. R2 bucket access remains under your control; HCTI does not make the object public.
Troubleshooting Cloudflare R2 uploads
The connection test cannot find the bucket — Confirm the bucket name, account ID, and data jurisdiction.
Authentication fails — Use the S3 Access Key ID and Secret Access Key generated for R2, not a general Cloudflare API token string.
The secret is unavailable — Create a new R2 API token; Cloudflare does not show the secret again after creation.
A later transformation fails with HCTI Storage disabled — Confirm the token has object read access as well as write access.
The connection worked before the jurisdiction changed — Test again; changing the jurisdiction changes the R2 endpoint.