Asset favicon.svg not served in prod

I use an svg favicon in my application.
My application was generated with the command: mix phx.new .

I added a favicon.svg file to assets/static.

In the layout file it is referenced as <link rel="icon" href="<%= Routes.static_path(@conn, "/favicon.svg") %>" />.

In dev mode this works. But when i run phoenix in prod mode the favicon is not served.

To build the assets i executed:

npm run deploy --prefix ./assets
mix phx.digest

This runs without any error and produces the following output:

ls priv/static/
cache_manifest.json                              favicon.svg     js                                              robots.txt
favicon-f518d411df681dc1e8258eb14b218a97.svg     favicon.svg.gz  robots-067185ba27a5d9139b10a759679045bf.txt     robots.txt.gz
favicon-f518d411df681dc1e8258eb14b218a97.svg.gz  images          robots-067185ba27a5d9139b10a759679045bf.txt.gz

In my browser devtools i can see that the favicon should be available here: <link rel="icon" href="/favicon-f518d411df681dc1e8258eb14b218a97.svg?vsn=d">.

But if i call this url nothing is returned.

/favicon.svg works though.

Here a part of endpoint.ex

  plug Plug.Static,
    at: "/",
    from: :typeracer,
    gzip: false,
    only: ~w(css fonts images js favicon.svg robots.txt

Does anyone know how i can make the favicon appear?

Make sure you add the prod env when doing mix phx.digest for production environment:

MIX_ENV=prod mix phx.digest
1 Like

Yes i do.
I wrote the following script to build the application:

#!/bin/bash

export MIX_ENV=prod
export PORT=4001
export URL_PORT=443
export URL_HOST=***
export DATABASE_URL=***
export SECRET_KEY_BASE=***


mix deps.get
mix compile
npm install
npm run deploy --prefix ./assets
mix phx.digest
mix ecto.migrate

Perhaps the Plug.Static explicit :only option is the cause of this. From the docs:

:only - filters which requests to serve. This is useful to avoid file system traversals on every request when this plug is mounted at "/". For example, if only: ["images", "favicon.ico"] is specified, only files in the “images” directory and the “favicon.ico” file will be served

Try to move the file inside a folder specified in the :only option and test like that.

Or, keep the favicon at the root, but move it to :only_matching:

:only_matching - a relaxed version of :only that will serve any request as long as one of the given values matches the given path. For example, only_matching: ["images", "favicon"] will match any request that starts at “images” or “favicon”, be it “/images/foo.png”, “/images-high/foo.png”, “/favicon.ico” or “/favicon-high.ico”. Such matches are useful when serving digested files at the root. Defaults to nil (no filtering).

4 Likes

This worked. Thanks. I moved it to the image folder.