rhyslees/nova-audio
A Laravel Nova field for handling audio files in your admin panel. Upload, store, and preview audio directly on Nova resources, with simple configuration for media playback and file management.
nova-audio is a Laravel Nova field that stores an audio file on a model attribute and renders an inline player (and upload control) inside the Nova UI. Version 3.0.0 adds Laravel 10 support, which in practice means it targets Nova 4.x and a modern PHP runtime — treat it as a Nova-4-era package.
Minimal steps:
composer require rhyslees/nova-audio (Nova itself must already be installed — it is a paid package and not pulled in by this one).Schema::table('tracks', fn (Blueprint $t) => $t->string('audio')->nullable());
use RhysLees\NovaAudio\Audio;
public function fields(Request $request): array
{
return [
Audio::make('Audio'),
];
}
php artisan nova:publish or the package's own vendor:publish tag if it ships one) — the field's JS/CSS lives in the package's dist/ directory.Where to look first: the package README for the exact field namespace and supported chainable options, then src/ for the field class to confirm inherited methods (it wraps Nova's file-upload behaviour), and dist/js/field.js if the player misbehaves. First real use case: attach a single MP3 to a resource, upload it in the Nova create form, and confirm it plays back in the detail view.
intro_audio, full_audio) rather than trying to store an array.->disk('s3'), ->path('audio/'.$this->resource->id), ->storeAs(fn () => Str::slug($this->title).'.mp3')) so uploads land where your app expects and URLs remain stable.->nullable() and a ->help() hint so editors can leave the field empty; guard playback in the frontend with @if ($track->audio).->exceptOnForms() for fields populated by an importer/job, and ->readonly() where the audio is generated server-side. Use ->hideFromIndex() if you don't want players rendered in the resource table.->rules('mimes:mp3,wav,ogg', 'max:20480'). The browser player is far pickier than the validator, so validate codecs you know play everywhere.config/filesystems.php and the field's disk consistently; a private disk without URL signing produces silent players.->canSee(fn () => $request->user()->can('update', $this->resource)) where media rights matter.dist assets are the single most common "upgrade did nothing / field broke" cause.2.0.2...3.0.0) before upgrading a production app, and pin ^2.0 if you are still on Nova 3 / Laravel 9.<audio> element; .mp3 and .m4a are safe, .wav is large but fine, .ogg/.opus is patchy on older Safari. If a file uploads but nothing plays, test the stored URL directly in a browser tab before blaming the field.storage:link, or a path mismatch after renaming the column — check the Network tab, not the PHP logs.upload_max_filesize / post_max_size truncate large audio before max: rules run, producing confusing "file is required" errors instead of a size message.File::make() on the same attribute. Two fields writing one column will fight over the stored path; pick one.composer update, run php artisan nova:publish (and any package publish tag) and hard-refresh the browser; cached mix/vite manifests in Nova can serve the old field JS.component/resolveUsing, or wrap it in a custom tool — don't hack the vendored dist files, since upgrades overwrite them.APP_DEBUG=true and inspect the field's props in the Vue devtools panel — the resolved file URL and disk are serialized there, which is the fastest way to see whether the problem is server-side storage or client-side rendering.How can I help you explore Laravel packages today?