dnsk-work / twill-r2
Twill fixes for Cloudflare R2 and S3-compatible object storage (URL generation, policy signing, safe deletion)
Requires
- php: ^8.1
- area17/twill: ^3.0
README
# Twill R2Three targeted fixes for Laravel Twill that surface the moment you run the media and file libraries on Cloudflare R2 — or any S3-compatible storage behind a custom endpoint: public URL generation, Fine Uploader policy signing, and safe deletion.
What it fixes
Public URL generation
Twill overwrites the disk's url to a local path when file_library.endpoint_type is local,
which breaks every public file URL on R2. This package reads FILE_LIBRARY_PUBLIC_URL instead,
decoupling URL generation from the disk config entirely.
Fine Uploader S3 policy signing
Twill's SignS3Upload::isValid() compares parsedMaxSize against (string) null, which always
fails when Fine Uploader includes a content-length-range condition — silently blocking every
upload. This validates by matching the bucket condition instead, keeping the full HMAC-SHA256
v4 signing logic intact.
Safe media & file deletion
Twill's afterDelete() lists the parent directory to tidy up empty folders. On R2 a malformed
AWS_ENDPOINT makes ListObjectsV2 throw, which rolls back the DB delete transaction and leaves
orphaned rows in twill_medias / twill_files. This wraps the cleanup in try/catch so the
database record is always deleted.
Requirements
| PHP | ^8.1 |
| Laravel Twill | ^3.0 |
Installation
composer require dnsk-work/twill-r2
The service provider is auto-discovered. Fixes 2 and 3 need no further setup.
For the public URL fix, add to config/filesystems.php:
'file_library_public_url' => env('FILE_LIBRARY_PUBLIC_URL'),
Then set FILE_LIBRARY_PUBLIC_URL in .env to your bucket's public base URL (e.g.
https://files.example.com). The override only activates when that key is present — without it,
Twill's default behaviour is preserved.
License
**[dnsk.work](https://dnsk.work)** — a UI/UX design agency without the agency part.Senior-led, embedded, no six-week process.