Configuring router.ex For Static Plug In Phoenix 1.3

I’m trying to set up Plug.Static in router.ex using Phoenix 1.3.

When using the format that static.ex inline documentation shows, i.e:

defmodule AppWeb.Router do
...
    plug Plug.Static,
      at: "/uploads",
      from: {:app_name, "uploads"},
      only: ~w(images robots.txt)
...
end

compilation fails with the message:

plug must be defined inside a pipeline

That’s expected; however, when attempting to define in a pipeline like this:

defmodule AppWeb.Router do
...
  pipeline :static do
    plug Plug.Static,
      at: "/uploads",
      from: {:app_name, "uploads"},
      only: ~w(images robots.txt)
  end

  scope "/uploads", AppWeb do
    pipe_through :static
  end
...
end

the route is not found and none of the files in the directory are served when requested.

So I guess I’ve got some incorrect assumptions at work and so my question is, how does one configure router.ex to use Plug.Static in Phoenix 1.3?

Thanks for your time & help!

I’m not sure why you want to have that plug in your router. Putting it in the Endpoint modules seems to be the better way. I mean there’s no routing needed for static stuff.

Your version probably does not work, because there’s no actual route in your scope.

Edit: Somehow thought you want to upload stuff. So scratch below.

scope "/uploads", AppWeb do
    pipe_through :static
    
   # Put routes here
   post "/", UploadController, :create
end

The scope is going to nest your routes. So you should either have at: "/uploads" and scope "/" or the opposite. Also remember that the plug is just invoked if there is a matching route. So it may be better for you to define a UploadController indeed and call the Plug.Static plug in there.

1 Like

Yep, as you have it they should be hosted at /uploads/uploads.

Thanks all for your replies!

I tried accessing via uploads/uploads and still see:

no route found for GET /uploads/uploads/derp.jpg (AppWeb.Router)

I imagine that’s expected since there’s no route shown when running mix phx.routes

Modifying the scope like this:

  scope "/", AppWeb do
    pipe_through [:browser, :static]
    
    get "/", PageController, :index
  end

seems to have no effect here:
➜ app git:(master) ✗ mix phx.routes

page_path  GET  /  AppWeb.PageController :index

It seems like offloading this to a controller is a much better route (bad joke alert) to take; it’s more explicit and more extensible.

Thanks again for your time & your replies!

Well it wouldn’t show a static plug regardless.

But yeah, it should be in the endpoint, not a router. I don’t think that plug will ever get called unless the router routes to a path in the router, which of course means the static plug would not handle it anyway. ^.^;