Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statamic Cloudinary Laravel Package

tfd/statamic-cloudinary

Connects Statamic to Cloudinary so images and assets are stored, managed, and delivered through Cloudinary's CDN. Configure the asset driver and serve optimized, responsive media from your Statamic site with minimal setup.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The addon occupies the correct seam in a Statamic application: it decorates the asset-rendering layer rather than replacing it. It registers through the standard Statamic addon contract (src/ServiceProvider.php), merges and publishes config to config/statamic/cloudinary.php, registers a view namespace (cloudinary), a Blade component (<x-cloudinary-image />), an Antlers tag (src/Tags/Cloudinary.php), and a wildcard {{ cloudinary:field }} surface. All transformation logic is centralized in TFD\Cloudinary\Converter\CloudinaryConverter, which is the right shape — a single translation point for Glide-style parameters into Cloudinary transformation syntax. The tag retains a Glide fallback, which means adoption is additive and reversible; the existing Statamic asset pipeline remains intact as a safety net. This is a delivery-offload addon, not a storage migration, which is architecturally the lower-risk posture. Note, however, that the architecture's safety net is only as good as its implementation: v1.5.1 reveals the fallback was structurally present but functionally broken on the wildcard surface, so "the fallback exists" must be read as a per-surface property, not a global one.

Integration feasibility. Mechanically low effort: composer require tfd/statamic-cloudinary, publish config, supply Cloudinary credentials via environment, then swap {{ glide:* }} / {{ asset }} call sites for the cloudinary tag or Blade component. No frontend build pipeline exists or is needed. The real feasibility question is not install cost but the mapping model: the docs confirm support for Statamic asset IDs, asset URLs, and mapped external URLs, but do not state clearly whether assets must already exist in Cloudinary or whether the addon relies on Cloudinary's remote-fetch delivery type to pull from the existing origin. That single decision determines whether this is a one-hour config change or a full asset-synchronization project.

Technical risk. The risks are predominantly supply-chain and verification, not design. v1.5.1 materially sharpens — but does not change the direction of — this picture:

  • The fallback was not reliable until 1.5.1. In v1.5.0, Tags\Cloudinary::wildcard() raised ArgumentCountError at both fallback sites rather than degrading. Two consequences: an install with missing/invalid Cloudinary credentials 500s on every {{ cloudinary:field }} tag, and a correctly configured install 500s as soon as a referenced asset is missing or is renamed. This is a hard availability bug on a runtime path, not a cosmetic one — missing assets are the normal steady state on content-managed sites. Pin >=1.5.1; treat 1.5.0 as unusable. Existing projects on 1.5.0 should be audited for wildcard tag usage and for assets deleted or renamed since adoption.
  • "Silent degradation" was the design, but 500s were the reality. The established error pattern elsewhere is to catch ItemNotFoundException, log at error level, and fall back to Glide. That pattern is sound for uptime and bad for observability — but on the wildcard path it wasn't even delivering uptime. Do not generalize the fallback guarantee across tag surfaces without testing each one.
  • Test coverage is still narrower than the declared support matrix, and was previously zero. The release notes confirm that prior to this version require-dev pinned orchestra/testbench ^9 (Laravel 11), and those releases were blocked by security advisories — meaning no test runner was installable at all. Every release through 1.5.0 shipped with no executable test suite. v1.5.1 adds the first tests for Tags\Cloudinary and repairs the harness, which is a genuine improvement, but the harness now runs Testbench 10 / Laravel 12 while the package declares Statamic ^5.73.11 || ^6.4. Statamic 5 on Laravel 10/11 remains claimed but unproven, and AGENTS.md still notes no CI matrix. The absence of CI is the mechanism by which a broken fallback reached a tagged release; until a matrix exists, assume this class of defect can recur.
  • Bus factor / adoption. 7 stars, 0 dependents, single-package governance, single maintainer. Still no ecosystem evidence of production hardening — and the 1.5.0 regression is now affirmative evidence to the contrary.
  • Provenance ambiguity. The repository lives under 21stdigital but the package and PSR-4 namespace are TFD\Cloudinary. That pattern suggests a fork, transfer, or vendored addon. Ownership and upstream-tracking cadence must be confirmed before committing.
  • Release-note hygiene. The summary claims "no behaviour changes beyond the fallback now working as it was always meant to," which is accurate for API surface but understates the operational delta: a 500 becomes a 200. Treat the notes as honest but conservative in framing rather than exhaustive. The previously observed future-dated release metadata (2026-07-29) remains a reminder to verify against Packagist/tags directly rather than trusting the changelog feed.

Key questions.

  1. Does URL generation assume the asset already exists in Cloudinary, or does it emit fetch-type URLs against the Statamic origin? What is the public_id derivation rule, and is it stable across renames? (The 1.5.0 bug makes rename-safety a first-class question, not a footnote.)
  2. Which Glide parameters are translated, which are silently dropped, and what happens on an untranslatable parameter — pass-through, ignore, or exception?
  3. Is the Glide fallback opt-out-able and alarmable, or does it always degrade silently? And now verified as relevant: which code paths have actually been exercised through the fallback, and is that set covered by tests or CI?
  4. Are signed URLs / authenticated delivery supported for private or protected assets, or does enabling this addon risk widening access to restricted imagery?
  5. Multi-site: are localized assets and per-site transform sets handled?
  6. Cache behavior: are generated URLs stable enough to sit behind a long-TTL CDN, and is there any purge/invalidation hook?
  7. Is the ^5 claim backed by any test run, or is it aspirational? What is the plan for a CI matrix, and is there a commitment (or fork posture) if it does not arrive?
  8. Are deleted/renamed assets expected in this content model, and how frequently? That determines the blast radius of the bug class just fixed.

Integration Approach

Stack fit. Designed for Laravel + Statamic 5/6 and PHP 8.x. It follows framework conventions (config merge/publish, view namespaces, Blade component aliasing) and introduces no queue workers, no migrations, no schema, and no service dependencies beyond the Cloudinary PHP SDK. That makes it a clean fit for conventional Statamic sites, including Blade/Livewire front-ends; it is a poor fit for headless setups where Statamic is not rendering the image markup, since the value is concentrated in the tag and component.

Migration path. Adopt in four reversible steps, with a hard version floor:

  1. Version gate. Require >=1.5.1 in composer.json. Do not allow the constraint to resolve to 1.5.0. If already on 1.5.0, upgrade before anything else and re-test deletion/rename behaviour.
  2. Shadow install. Add the dependency and publish config on a staging branch with Cloudinary credentials present but the addon not yet used at any call site. Confirm the service provider boots, the component renders, and nothing in the existing Glide path changes. Then deliberately run the negative cases: unset the credentials and reference a nonexistent asset — the wildcard tag must render via fallback, not 500.
  3. Single-surface pilot. Move one template partial or one asset container's rendering to {{ cloudinary }} / {{ cloudinary:field }} / <x-cloudinary-image />. Keep the Glide fallback enabled. Explicitly include the wildcard tag in the pilot, since that is the surface with the newest and least-proven test coverage. Diff the emitted URLs and measure bytes and TTFB against the Glide baseline.
  4. Parameter parity audit. Build an explicit mapping table of every Glide parameter currently in use in the codebase against the converter's supported set. Anything unmapped is either removed, handled in the template, or treated as a blocker for that call site. Do this before broad rollout, not after.
  5. Progressive rollout. Enable by template area or by site, with the fallback still armed, then decide deliberately whether to also migrate asset storage to Cloudinary or stay dual-source (Statamic as system of record, Cloudinary as delivery). Dual-source is the materially safer default.

Compatibility. Pin to the addon's declared Statamic range and to >=1.5.1, and validate against the Laravel version actually deployed — do not inherit the addon's test-harness result, since after 1.5.1 it only exercises Laravel 12. If the project runs Statamic 5 on Laravel 10/11, budget an explicit smoke-test pass on the real runtime; that combination has now been proven to have had no runnable test suite for the package's entire release history. The MIT license is a genuine asset here: if upstream lags a Statamic release, forking and maintaining an internal copy is legally and technically uncomplicated.

Sequencing. Version gate first (1.5.1 floor). Secrets management and Cloudinary account provisioning next. Negative-path testing of the fallback must precede any template change — the fallback is the entire risk-mitigation story, and it was broken as recently as one patch release ago. Parameter parity audit must precede broad rollout. Cost modeling (transformations, bandwidth, storage) must precede the storage-migration decision. Template migration should never precede the audit — otherwise unmapped parameters surface as visual regressions in production rather than in a diff.

Operational Impact

Maintenance. Small surface area (service provider, converter, one tag, one component, one view) and conservative conventions keep code maintenance cheap. Two counterweights. First, the dev toolchain itself was broken until this release — an uninstallable test harness means dependency bumps to require-dev can silently disable verification, so CI must assert that the suite actually runs, not merely that it exists. Second, upstream tracking: Statamic 5→6 already crossed a major boundary, the Cloudinary SDK moves independently, and 1.5.0→1.5.1 demonstrates that patch releases can carry availability-relevant fixes. Assign an internal owner, treat the addon as a fork-in-waiting, and adopt a standing rule: bump to patch releases deliberately, read the changelog, and re-run negative-path tests. Because composer lint runs php-cs-fixer fix (mutating, not dry-run), CI should use the dry-run variant explicitly.

Support. Community-only, effectively single-maintainer, negligible installed base, no commercial SLA and no meaningful issue-tracker signal at 7 stars. The 1.5.1 fix shows the maintainer is responsive and does repair regressions — a positive signal — but also that a defect of this severity can ship and persist for a full version cycle. Acceptable for a delivery-layer utility provided the fallback is verified and alarmed; unacceptable for anything in the critical path of a revenue-bearing page without an internal fallback plan. Contractually: assume you own the code the day you adopt it.

Scaling. This is the addon's strongest argument. Image transformation is CPU- and IO-heavy on the origin; pushing it to Cloudinary removes that from your web tier and gives you a global CDN and modern format negotiation (AVIF/WebP) without running Glide at scale. Two new ceilings replace the old one: Cloudinary plan quotas (transformations/month, bandwidth, storage) and API rate limits on any upload/sync path. Both are manageable but must be metered from day one — transformation overage is a classic silent-budget incident. Also confirm cache-key stability, since unstable URLs defeat CDN efficiency and quietly inflate cost. Worth modeling explicitly: until 1.5.1, a missing asset produced a 500 on the wildcard path, and 500s are not cacheable and not cheap — a content hygiene problem could have become an origin-capacity problem.

Failure modes. Enumerate and instrument these before go-live:

  • Cloudinary outage → Glide fallback fires; site stays up but origin load spikes. Ensure the fallback path is capacity-tested, not just code-present.
  • Credential or config error → historically: a 500 on every wildcard tag (missing credentials); intended behaviour is silent fallback plus a logged error that nobody reads. On >=1.5.1, alert on the fallback log line and on Cloudinary error rate; otherwise misconfiguration is invisible indefinitely.
  • Missing or renamed asset → the highest-frequency trigger, and the exact input that crashed v1.5.0. Confirm on the deployed version that this yields a fallback render, and monitor 5xx rate on image routes as a standing canary.
  • Mapping drift → asset renamed or moved, public_id derivation changes, images 404. Pin the derivation rule and test it.
  • Access-control regression → wrong delivery type exposing private assets. Verify before enabling on any restricted content.
  • Cache poisoning → a transient Cloudinary error caches a fallback URL behind a long TTL, degrading delivery for the TTL window. Keep fallback responses short-lived or uncacheable.
  • Cost runaway → an unmapped parameter generating per-request unique transformations. The parity audit doubles as cost control.
  • Regression reintroduction → no CI matrix means the fixed bug class is not structurally prevented. Compensate with your own smoke test against the pinned version.

Ramp-up. Developer ramp-up remains small — an afternoon to read the config, converter, tag, and the new Tags\Cloudinary tests, and to render the component in a scratch template. Operational ramp-up is the real cost and has grown slightly: Cloudinary account and billing ownership, a documented kill-switch procedure for the addon (revert to Glide), a runbook for credential rotation, dashboards covering transformation count, bandwidth, error rate, and fallback frequency, plus a negative-path smoke test (no credentials, missing asset, wildcard tag) added to the deploy checklist. Budget roughly one engineer-week end-to-end for a mid-size site — mostly parity auditing, observability, and now fallback verification, not integration.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route