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

Nova Media Field Laravel Package

stepanenko3/nova-media-field

Laravel Nova field for adding media uploads and management to Nova resources. Attach and preview images or files directly in the admin panel, with a simple, customizable field that streamlines media handling in Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisites. Laravel Nova (verify against your installed major version — the package's last release was March 2024) and spatie/laravel-medialibrary already installed and migrated on the target model. The field is only a UI shell over medialibrary; nothing works until the model is a proper media host.

  1. Install the field:
composer require stepanenko3/nova-media-field
  1. Make the model a media host and declare a collection. The collection name is the contract between your model and the Nova field:
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Post extends Model implements HasMedia
{
    use InteractsWithMedia;

    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('cover')
            ->singleFile()
            ->acceptsMimeTypes(['image/jpeg', 'image/png', 'image/webp']);
    }
}
  1. Add the field to the Nova resource, pointing at that same collection:
use Stepanenko3\NovaMediaField\MediaField;

public function fields(Request $request)
{
    return [
        MediaField::make('Cover')
            ->collection('cover')
            ->disk('public')
            ->accept('image/*')
            ->rules('max:4096'),
    ];
}

Method names (collection, disk, accept, single, maxFiles, preview) are the ones this package family exposes; confirm exact casing against the README before you build a form around them.

  1. Link storage and smoke-test:
php artisan storage:link

First use case to ship: a single cover/avatar image on one resource. It exercises the full loop — upload → attach to collection → render preview in index/detail → read back with $model->getFirstMediaUrl('cover'). Once that path is green, multi-file galleries and conversions are incremental.

Where to look first: the README's usage example, then the field's PHP class (src/) to confirm which fluent setters actually exist, then your model's registerMediaCollections(). Bugs here are almost always a mismatch between #2 and #3, not the package.

Implementation Patterns

One field per collection. Don't try to drive multiple collections from a single field. Build a gallery resource with cover (single) and gallery (multi) as two separate fields and two separate addMediaCollection calls.

Separate form and display concerns. Uploads belong on forms; previews belong on index/detail. Compose the field twice rather than one field doing both:

MediaField::make('Cover')->collection('cover')->disk('public')
    ->onlyOnForms(),

MediaField::make('Cover')->collection('cover')
    ->preview(fn ($value, $resource) => $resource->getFirstMediaUrl('cover', 'thumb'))
    ->exceptOnForms(),

Pair with conversions, not originals. Register a thumb conversion on the model and reference it in the index preview. Listing 20 rows that each pull a 4MB original is the classic Nova slowdown:

public function registerMediaConversions(?Media $media = null): void
{
    $this->addMediaConversion('thumb')->width(200)->height(200)->nonQueued();
}

Let medialibrary own the read path. The Nova field is an admin input, not an API. Everywhere else — Blade, JSON resources, sitemaps — read via getFirstMediaUrl('cover', 'thumb') or getMedia('gallery'). This keeps your front end working if you later swap or drop the field.

Multi-file galleries. Use a multi-file field on a non-single collection, and add ordering support on the model side (order_column) if the UI exposes drag-to-reorder. Treat the media order as data: if order matters publicly, expose it and assert it in a test.

Validation belongs on the field and the collection. ->accept() is a picker hint; ->rules('mimes:jpeg,png,webp', 'max:4096') is the enforcement, and acceptsMimeTypes() on the collection is the backstop for programmatic uploads. Set all three consistently or you'll get 500s from medialibrary on files the browser happily allowed.

Testing strategy. Test the media layer, not the Vue component. Use Storage::fake('public') and UploadedFile::fake()->image('cover.jpg'), attach via $post->addMedia(...)->toMediaCollection('cover'), assert getFirstMediaUrl and that the conversion exists. Exercise the Nova field itself with a single manual or Dusk pass per release; field-level feature tests have poor payoff-to-effort here.

Gotchas and Tips

  • Mismatched collection names fail silently. A field pointing at cover when the model registers covers renders empty with no error. If the field is blank on a record that has media, diff the strings first.
  • Missing storage:link or wrong disk. disk('public') on the field must match the collection's useDisk()/filesystem config. Mismatch produces broken previews while the upload "succeeds."
  • Queued conversions break previews. If conversions are queued, the index thumbnail 404s until the worker runs. Either nonQueued() the small thumbnails or ship a placeholder fallback in preview().
  • Orphaned files. Deleting a Nova resource with media attached leaves files on disk unless the media cleanup / cascade is wired. Audit the media table for records whose model_id no longer resolves before you assume deletion is complete.
  • Readonly fields can't upload. If you conditionally disable the field (->readonly() via canSee/dependsOn), remember attachments won't be written — a common "it works for admins but not editors" bug.
  • Nova major-version drift. With a March 2024 release and a small star count, treat Nova 5 compatibility as unverified. Pin the package and Nova versions together in composer.json, and do a real form save on upgrade — asset compilation and field-registration changes usually surface there, not in tests.
  • Small maintenance surface. 18 stars means you are effectively on a fork track. It's a thin field: if you need custom behavior (a media library picker, per-collection reordering, an S3 presigned preview), subclass the field and override the preview/component rather than patching vendor/. Keep that subclass in app/Nova/Fields/ so composer update can't eat it.
  • Debugging blank fields. In order: collection name → disk config → media table row exists → conversion exists → file exists at the generated URL. That sequence finds it in under two minutes every time.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib