I was able to learn a bit about this, and while this is not a complete answer, I will post what I found below for everyone's benefit.
According to this GitHub issue, MetaMask uses a third-party service called https://faviconkit.com/ in order to populate its favicons. I suspect that Coinbase Wallet may also use it, and maybe also TrustWallet. this service has essentially 0 documentation.
By running a local server, tunneling to it using ngrok, and hitting the external tunnel endpoint with faviconkit.com, I was able to learn which items faviconkit requests in order to populate its favicons. in summary, I found it was enough to do two things:
- use the webpack plugin
FaviconsWebpackPlugin when you build your project with webpack. use the default configuration. This will result in an
assets/ subdirectory in your output directory, containing a bunch of images (about 40 total or so).
- in your main output directory, run
cp assets/* .. That is, duplicate everything in the
assets/ folder to the main (top-level) output directory. do not move them; you must duplicate them.
if you do these two things, it seems that you will satisfy faviconkit. BUT there is a further problem—faviconkit is extremely slow to re-cache / refresh, and it is likely that your dapp will have stale favicons for a long time. it has been about a week, and my favicons have NOT refreshed. i do not know of a way to force a refresh of my dapp with faviconkit. hopefully this helps.