A self-contained LiveComponent for media uploads and gallery display.
MediaLive eliminates all upload boilerplate. Drop it into any LiveView
and get drag-and-drop uploads, live previews, progress bars, a media
gallery with delete support, and automatic persistence via PhxMediaLibrary
— all in a single line of template code.
Quick Start
<.live_component
module={PhxMediaLibrary.MediaLive}
id="post-images"
model={@post}
collection={:images}
/>That's it. No use PhxMediaLibrary.LiveUpload, no handle_event clauses,
no allow_upload, no consume_media. The component handles everything.
Options
<.live_component
module={PhxMediaLibrary.MediaLive}
id="album-photos"
model={@album}
collection={:photos}
max_file_size={20_000_000}
max_entries={20}
responsive={true}
upload_label="Drop photos here"
upload_sublabel="JPG, PNG, WebP, GIF up to 20MB"
compact={false}
columns={4}
conversion={:thumb}
show_gallery={true}
/>Parent Notifications
The component notifies the parent LiveView via send/2 so you can react
to uploads and deletions (update counters, refresh related data, etc.):
def handle_info({PhxMediaLibrary.MediaLive, {:uploaded, :photos, media_items}}, socket) do
{:noreply, assign(socket, :photo_count, socket.assigns.photo_count + length(media_items))}
end
def handle_info({PhxMediaLibrary.MediaLive, {:deleted, :photos, _media}}, socket) do
{:noreply, assign(socket, :photo_count, max(0, socket.assigns.photo_count - 1))}
endYou can safely ignore these messages if you don't need them.
How It Works
Internally the component:
- Calls
allow_upload/3with collection-aware defaults (accept types, max entries, max file size) derived from your schema's collection config. - Renders a single
<.form>containing a<.live_file_input>, drop zone, entry previews with progress bars, and a submit button. - On submit, calls
consume_uploaded_entries/3and persists each file viaPhxMediaLibrary.add/2 |> to_collection/2. - Streams existing + newly uploaded media into a gallery grid with delete-on-hover support.
Because the component owns its own <.form>, there is no nested-form
problem. The upload binary transfer and consumption work correctly.