I have a component rendered in my root.html.heex layout. It doesn’t update as I navigate through live routes. I have to refresh my browser to get it to pick up changes. I’m debugging inside my component, so I know that’s it not even being called the other times.
<%= if assigns[:favicon] do %>
<IdoWeb.EmojiComponents.favicon emoji={@favicon}/>
<% end %>
The @favicon assign is being set / changed as I navigate, but the .favicon component isn’t added/removed/updated. What am I missing?
Note also that this will raise if the assign isn’t set. You should make sure to set a nil default, preferably using the new attr if you’re on LiveView 0.18:
attr :favicon, :string, default nil
def my_component(assigns) do
…
end
If you are using an earlier version, you can do
def my_component(assigns) do
assigns =
assigns
|> assign_new(:favicon, fn -> nil end)
…
end
Assigning a default in my component still fails. Just referencing the @favicon from heex causes an error. And I can’t just assign a nil value as a default higher up, because this is in my root layout- I’d have to assign a value for every single live view in the future. I thought this is why the root layout is using assigns[:page_title] rather than @page_title. And it updates properly for it.
Note: if I try to pass favicon (or even page_title) as an attribute, the component has the same issue- it’s never called to re-render:
I may be asking the wrong question. Is it possible to add/remove/modify things in the HTML <head> tag with liveview? It works for the slot of the .live_title component, but is that a special case that Phoenix knows how to update over the wire?
I think you’re onto something here. I’m heading off to bed, but yes: LiveViews are (to my knowledge) somewhat “scoped” to the root at which they’re rendered, whereas .live_title is a sort of “special case” that is available by default because it is a common use-case.
This does not mean that what you’re trying to accomplish isn’t possible, but it may mean a bit of extra boilerplate to get it all working.