duncanphillips
Keeping a side navigation components open/close state
Hi,
I have a site layout which has a side navigation which is collapsible (i.e. it has a button to make wider/thinner). One thing that I can’t quite figure out the best approach for is how to keep the open/close state persisted between page transitions. So if the default is open, and I navigate to another page, it will always go back to the open state. I was thinking about maybe using a JS hook and local storage, but wanted to see if others have solved this more elegantly?
Side note on the open/close implementation:
I’m using a data attribute for the open/close state, in conjunction with some CSS rules.
<aside
id={@id}
class="w-20 data-[state=open]:w-[250px] transition-[width] ..."
data-state="open"
phx-update="ignore"
>
...
</aside>
thanks
Marked As Solved
codeanpeace
For persisting when navigating across liveviews or live sessions, you could live render the sidebar as its own “sticky” liveview.
Another option is to append that sidebar state to the url as parameters, but not sure how elegant that is for this use case.
Also Liked
rhcarvalho
The LiveView, and particularly the sticky LV, is the abstraction for compartmentalizing state (and events).
If you want to keep the state on the server, then sticky LV is a good option, I had a positive experience implementing a similar navigation component after making a similar question myself.
The phx-update="ignore" and local/session storage direction is if you prefer to keep the state in the browser only.
Both options are viable. State on the server opens up some creative possibilities, like syncing the state across tabs, easily “studying” how users use the UI, remote-controlling the UI, conditional events based on UI state, etc.
duncanphillips
Thanks for the input, seems like I should take another look at the sticky liveview ![]()
rhcarvalho
Coming back to this, I wanted to share that there are other options worth exploring that don’t involve a separate (sticky) LiveView.
For instance, one can save the open/close state on the client using localStorage and then pass it as params to the LiveSocket, see the example in the docs at Phoenix.LiveView.get_connect_params/1.
For a collection of this and other techniques, there’s a talk from ElixirConf EU 2025: Phoenix LiveView: Mastering Reconnects for a Seamless User Experience -Giovanni Francischelli.







