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

Twill Image Laravel Package

area17/twill-image

Twill Image adds responsive image rendering to Laravel's Twill CMS. It generates picture and source markup with named crops, srcset breakpoints, lazy loading, and low-quality placeholders, so editors can manage media in Twill while front-end images stay fast and correctly sized.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require area17/twill-image. The package targets Laravel 11/12 (12.x support was added in v2.1.0) and pairs naturally with Twill, but also works in a plain Laravel app if you provide a media model.
  • Publish the config immediately: php artisan vendor:publish --tag=twill-image-config. This gives you config/twill-image.php — the single place for breakpoints, formats, and transformer settings.
  • Configure a transformer first, because nothing renders without one. You can use a local transformer (e.g. area17/twill-image-local) or a remote/cloud one (Imgix). The transformer is what turns a media record + crop + dimensions into actual URLs.
  • Point the config at your media model. In a Twill app this is usually the default Twill media model; in a non-Twill app you'll map it to your own model that exposes width/height/path accessors.
  • First use case: replace a hard-coded <img> in a hero block with the package's responsive image output. Render one image, pass a crop/aspect ratio, and confirm you get a <picture> with srcset for the configured formats. That validates the whole install (config → media model → transformer → URL generation) in one step.

Where to look first: config/twill-image.php, then the package's Blade component(s) and README section on the transformer. Do not start by editing CSS; get a URL rendering out of the transformer before styling anything.

Implementation Patterns

  • Blade-first usage. Use the package's Blade component/tag for rendering. Pass the media object, crop name (or array), and any sizes/aspect ratio metadata. Keep image markup behind this component so responsive behaviour is consistent across the app.
  • Centralize breakpoints and formats in config. Define your srcset widths and output formats (e.g. webp, avif, jpg fallback) once, then reuse them everywhere. Per-page overrides should be rare.
  • Crop presets as a workflow. Define named crops (hero, thumbnail, card) that map to fixed aspect ratios. Twill authors then pick crops in the CMS, and your Blade just references the preset — decoupling content decisions from layout.
  • HasMedias integration. In Twill models, attach media via the media trait and reference the role/collection when rendering. In non-Twill apps, wrap your own model and expose the same width/height accessors so the component stays agnostic.
  • Lazy loading and LQIP are opt-in patterns. Add loading="lazy" and, where supported, a low-quality placeholder or blur-up. Treat these as component props, not hard-coded attributes, so above-the-fold heroes can opt out of lazy loading.
  • Swap transformers by environment. Use a local transformer in dev/CI (no external dependencies, no signed URLs) and a remote transformer (Imgix or similar) in production. Keep both configs in the same file and select via APP_ENV or a dedicated env var.
  • Cache-bust on media updates. When media changes, generated URLs should reflect the new file version. Wire this into your media save/update flow so caches (CDN, HTTP) don't serve stale crops.

Gotchas and Tips

  • v2.1.0 is a compatibility release, not a behaviour change. It only adds Laravel 12.x support. If you're on Laravel 12, upgrade to pick it up; there are no breaking changes in this release, so no code changes should be required from 2.x users.
  • Config cache bites. After editing config/twill-image.php in production, run php artisan config:clear (and config:cache if you cache). Stale config is the most common "nothing changed" bug.
  • Missing transformer = no URLs. Symptom: empty src or exceptions on render. Check that a transformer is bound and its driver is installed before debugging the media model.
  • Transformer URLs must be reachable. With remote transformers, signed/expiring URLs, firewall rules, and localhost cannot be rendered server-side for external services — this is why local dev often needs the local transformer.
  • srcset needs real aspect ratios. If your media has no width/height (e.g. not yet processed), crops compute wrong or fail. Ensure dimensions are persisted/available, or generate them on save.
  • <picture> source order is significant. Browsers pick the first matching source; ordering formats from best (avif/webp) to fallback (jpg) matters. If a format seems ignored, check ordering and the type attribute.
  • Lazy loading above the fold hurts LCP. Don't blanket-apply loading="lazy"; make it a prop and leave hero images eager.
  • Debugging tip: log the generated src/srcset from the component and open a single URL directly in the browser. If the transformer returns a 404/403, the issue is transformer config, not the package.
  • Extension points: the transformer contract and the media model interface are the two places to extend. Custom transformers (e.g. for a different CDN) and custom media models let you adapt the package without forking.
  • Keep an eye on the package's Laravel constraint when upgrading Laravel. This release is the one that unblocks Laravel 12; older tags may refuse to install on 12 even if they work.
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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums