BartOtten
Proposal
- Support DOM patching of the HTML link element for a favicon.
- Add the special @page_favicon assign mimicking the @page_title assign so each page can have it’s own dynamic favicon; supporting multiple tabs for an application with different ‘statuses’.
Reason
Many modern web applications have dynamic favicons. These dynamic favicons are used to notify browser users of events or statuses. For example: unread messages or a CI build status. As those use cases are quite common, providing such functionality seems to fit the ‘no Javascript’-philosophy. Additionaly it seems to align with the automagic @page_title.
Because the root layout from the Plug pipeline is rendered outside of LiveView, the contents cannot be dynamically changed. The one exception is the
<title>of the HTML document. Phoenix LiveView special cases the@page_titleassign to allow dynamically updating the title of the page, which is useful when using live navigation, or annotating the browser tab with a notification. For example, to update the user’s notification count in the browser’s title bar, first set thepage_titleassign on mount
Live layouts — Phoenix LiveView v1.2.5
Current State
- The HTML
linkelement for favicons is placed inlayout/root_live.html.heex. No native logic is in place to update it in the DOM and there is no @page_favicon. - The HTML
titleelement is placed in `layout/root_live.html.heex. Native logic is in place to update the element in the DOM when the @page_title assignment is changed.
Todo
- get approval for feature
- research possibilities
- draft design
- get approval for design
- implement
I am willing to work on this as contribution to the community.
Links
[LiveView Dynamic Favicon?]
[https://medium.com/@alperen.talaslioglu/building-dynamic-favicon-with-javascript-223ad7999661]
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










First 10 of 22 Posts
AndyL
Here is a working prototype for Dynamic Favicon. A streamlined solution that follows the style of live_title_tag would be great. I will help.
AndyL
Here’s some rough design ideas:
Let there be a special assign
@favicon_hrefThe
live_favicon_tagwould go intolayout/root_live.html.heexThe
live_favicon_tagfunction would emit the following HTMLAdd an event listener to the client javascript
On the server, when the LiveView process detects that
@favicon_hrefhas changed, push an event to the client:With this approach, add-on packages (like
live_dashboard) could add their own favicon images topriv/images, and then use their own favicons in their particular LiveViews.josevalim
Awesome job @AndyL! I am not sure if this is such a common use case to warrant inclusion on LiveView, but that’s all the pieces needed for anyone who wants to roll with it.
PJextra
It would be a great quick win!
BartOtten
Great example!
The other option is to keep is really simple and let a lib handle more advanced usecases
AndyL
Didn’t know about SVG icons - super nice! Pretty well supported on desktop browsers, less on mobile. Also learned that people sometimes use multiple favicon links, to give browsers an way to fall back to supported types.
I think there are two alternatives to attack this problem: manual coding like I did in the prototype, or editing LiveView itself. I don’t think this can be done with a Library, because there is no way for a Library to inject behavior into the LiveView JS. Is this right?
I looked in the LiveView code to understand
live_title_tag- there seems to be three key areas in the code:The code itself looks pretty straightforward - with a good amount of testing support.
Generating the appropriate favicon mime type could be done by checking the file extension of the href - this could be done in the javascript.
I’m not sure what the size opt does - I’ve always used ‘auto’ size.
If we could do something simple to streamline the 80% case, people could always fall back to a manual approach if needed.
BartOtten
Chose to keep the assign key generic; not sure of we can pass components to it (its too late).
If we can the favicon_tag function can use the (to be updated) DOM diffing too as no attribute is in the name. This allow for the simple approach by default using it as href when assigned a binary. Keeping the advanced usage of favicons to a lib which can simply pass a full icon link element.
Too be continued….first let’s see if the draft PR survives the public exposure.
https://github.com/phoenixframework/phoenix_live_view/pull/2087
Won’t take long before you can play Doom in the browsers` tab bar…
AndyL
PR looks great - beautiful screen shot!
I’m curious - did you intend that it should be possible to update multiple favicon links, or just one? If multiple: would you assign an array of hrefs to
@favicon, or use some other convention?BartOtten
Last night I looked at support for multiple icons
Phoenix LiveView is awesome at diffing and sending the least amount of data over the wire. I am trying to keep that in honor. As a result I have chosen to use a simple string replace.
The free schema also makes it easier to use online favicon generators that generate a bunch of PNG files for you. Just unzip and place in a subfolder of a variant. SVG scale so don’t need a subfolder. See pseudo code:
When a new @dynamic value is assigned, the href is split in 3 parts: prefix, @dynamic and suffix. The dynamic value is replaced with the value assigned.
static: /images/status/
dynamic: “new_message”
static: /favicon-32x32.png
Only the dynamic part is sent over the wire on socket assign updates. Just like…LiveView does already
When href is defined without a dynamic, the helper assumes the user needs full control over the href and just passes it through. Thus supporting base64 encoded data and one-off use cases.
This also allow me to add ‘class’ to support those fancy dynamic SVG’s.
As you like screenshots:
BartOtten
Update: the draft PR is rejected
Not sure if the presented solution really covers the use cases as mentioned above. It does cover the simple first case in the draft though, so it’s not a surprise. Will check later.