Allow default uploader when using external uploaders in LiveView

In the current implementation of Phoenix.LiveView.Upload, when you configure external: &function/2, it becomes mandatory to specify an uploader.

This makes sense in most cases, but there’s an important limitation: Once you introduce even a single external uploader, you lose the ability to fall back to the default built-in uploader.

This can be problematic when you want to mix different uploader strategies depending on the file — for instance, using a custom external uploader for images, but sticking to the built-in uploader for PDFs or other files.

I’ve patched LiveView locally to support falling back to the default uploader even when external: &function/2 is set — and it works well in my testing.

defmodule MyApp.SampleLive do
  ...
  def mount(_, _, socket) do
    socket =
      socket
      |> allow_upload(:files, external: &presign_upload/2)

    {:ok, socket}
  end

  defp presign_upload(entry, socket) do
    meta =
      case entry.client_type do
        "image/" <> _ -> %{uploader: "S3", presigned_url: "..."}
        _ -> nil
      end

    {:ok, meta, socket}
  end
end

If simply returning nil for the uploader in meta seems inappropriate, alternatives like %{uploader: nil} or %{uploader: :default} could be used instead.

If this sounds like a reasonable enhancement, I’d be happy to polish the implementation and open a PR. I think this could make LiveView uploads more flexible without breaking existing behavior.

1 Like