folklore/laravel-mediatheque
Laravel Mediatheque is a media library package for Laravel that simplifies uploading, storing, and attaching files and images to Eloquent models. It provides a clean API for organizing media collections, handling storage disks, and serving assets, keeping media management consistent across your app.
laravel-image v2 turns image files into URLs through resolvers: each resolver owns a URL shape and maps it to a file on a source (a disk). The v2.0.0-alpha.2 release adds the media resolver, which plugs laravel-image into your media records so you never hand-build image paths again.
composer require laravel-image/laravel-image:2.0.0-alpha.2 (or set minimum-stability: alpha / prefer-stable: true). Do not float on ^2.0@alpha in anything you ship.docs/decisions/0013-media-resolver-for-laravel-image.md first — it is the spec for the new resolver and the fastest way to understand the URL contract.laravel-image sources. A disk that isn't a known source is the most common reason a URL won't resolve.med_{id} — the media's primary image filemed_{id}/{handle} — a named conversion/handlemed_{id}/{handle}/{index} — a specific file when the media holds several (e.g. a multi-file collection or responsive variants)If you're coming from v1, treat this as a rewrite of how URLs are produced, not a patch: resolvers, sources and versioning all changed.
Let the resolver build the URL, never string-concatenate. The URL embeds a version derived from the file's checksum (first 8 hex chars) and a source derived from the file's disk. Hand-writing med_123/thumb will work until the file is replaced or moved, then silently serve stale or broken images.
Generate at render time. In Blade, resolve inside the template (src, srcset, og:image) rather than storing URLs in the database. Because the version segment tracks the checksum, a re-upload automatically produces a new URL and busts caches for free — but only if you regenerate.
Use {index} for multi-file media. For a gallery or an art-directed set, loop the files and emit one URL per index; for the common single-file case, omit it. Build srcset from handles rather than from raw paths.
Separate public and private rendering paths. Public media resolve to public sources and can be cached at the edge. Private media resolve to private sources — those URLs are app-served and often short-lived, so keep them out of long-lived caches, out of sitemaps, and out of anything you email. Branch on visibility in your presenter/view model instead of hoping the URL is harmless.
Guard on the record being present and alive. Deleted media don't resolve at all. Prefer $media?->... / a null-object placeholder (data:image/svg+xml or a static fallback) so a hard-deleted or soft-deleted record degrades to a placeholder rather than a broken <img>.
Rely on the auto-registration. The media resolver registers itself when laravel-image is present, even if another provider built its resolver list first (the #60 fix). Do not re-register it manually — double registration is at best a no-op and at worst puts an ambiguous pattern in the list. Only reach for explicit registration if you are deliberately overriding behaviour in a test.
Add custom resolvers for your own shapes. If you have CDN paths, legacy /uploads/... URLs, or external buckets, write a resolver with a distinct prefix and register it alongside the media one. Keep med_ reserved so third-party resolvers can't shadow it.
Test the URL, not the HTML. Assert the resolved URL contains the med_ prefix, the expected handle, and that swapping the underlying file changes the version segment. Assert a deleted media record resolves to nothing/throws as designed.
2.0.0-alpha.2; the URL grammar and resolver API can change before stable. Pin the exact version, isolate resolution behind a small presenter/helper, and re-read docs/decisions/ on every bump.med_123/thumnail simply doesn't resolve — the image 404s with no exception in the happy path. Validate handle names in a test or a config-level allowlist rather than discovering typos in production.Cache-Control headers, and don't let a private URL leak into a shared cache layer or a queued email payload.How can I help you explore Laravel packages today?