Just uploaded image doesn’t render in img immediately (404) until reloaded

An image is successfully saved to priv/uploaded and shows correctly in img src, but initially shows up as a broken image with status 404. When I right click and load the image it renders correctly. Any ideas?

I had to remove uploaded folder from the watcher to avoid constant restarting, and to add uploaded to the list of served static folders.

Might be the file name?

When requesting a file with name containing non-ascii or special characters, you should use urlencoded form.

Is your endpoint.ex configured to serve uploaded files statically?

You can add this option to Plug.Static:

only: ~w(css fonts images js favicon.ico robots.txt upload),

Yes, static_paths include “uploads”.

def static_paths, do: ~w(assets uploads fonts images favicon.ico robots.txt)

  plug Plug.Static,
    at: "/",
    from: :project,
    gzip: false,
    only: ProjectWeb.static_paths()

Apparently when DOM item gets inserted by app.js, the image request is strangely going through a regular non-static route first:

Then, when I right click the image, and choose Reload image, it shows up with a log:

This is my rendering portion:

        <div class="flex gap-4 flex-wrap">
          <div :for={entry <- @uploaded_files}>
            <span class="w-[1/4]">
              <img src={"/uploads/#{entry}"} alt={"/uploads/#{entry}"} />
            </span>
          </div>
        </div>

I’ve decoupled the route from the main static Plug, just to isolate the issue. Here’s my current state of things:

endpoint.ex:

  plug Plug.Static,
    at: "/",
    from: :project,
    gzip: false,
    only: ProjectWeb.static_paths()

  plug Plug.Static,
    at: "/uploads",
    from: {:project, "priv/static/uploads"},
    gzip: false

And under the main project_web.ex just to add it to the verified routes:

def uploads_paths, do: ~w(uploads)

def verified_routes do
  ...
  statics: static_paths() ++ uploads_paths()

The actual rendering is happening inside a LiveComponent as so:

div :for={entry <- @uploaded_files}>
  <span class="w-[1/4]">
     <img src={~p"/uploads/#{entry}"} alt={"/uploads/#{entry}"}

So far the issue remains. The <span><img /> shows up, but it’s only an alt. Same exact thing - initial request by the browser returns 404, and if I right click Reload, the image actually renders. Wrapping the path in url() does the same weird thing.

I tried to disable my anti virus, and it’s not an issue :smiley:
What else am I possibly missing?

Alright, I think, I managed it to work without 404 with a pipeline :static / scope pipe_through :static approach, but now I’m wondering what was wrong with just a regular plug?