What are the valid use cases for nested LiveViews?

I ran into code where one LiveView’s heex is calling another one throughlive_render.
While I think this particular code is not optimal, I wonder: Since the introduction of Components and LiveComponents, are there any valid use cases to nest LiveViews?

2 Likes

I could see library authors leverage this.

I’ve wondered the same. I’m still not sure :smiley:

Nested LVs are still useful for failure isolation, individual message passing capabilities and becoming sticky, which live components can‘t.

All of those are more niche usecases though.

6 Likes

Yeah being able to make a child LV sticky is what makes it interesting. We use that for UI elements that should persist while navigating between views, like an audio/video player, and a “new post” input box.

2 Likes

I’ve used them for exactly same use-cases. The only thing that I can’t shake off is that there is actually zero support for them and using them feels always like a hack, I mean you can plug in something like PubSub for communication, but still.

3 Likes

Nested LiveViews are very useful when building an app that’s having concurrent mostly-independent yet subordinated (as in children) flows of execution that are otherwise synchronous in nature on their own. The app I am now building has the following setup:

  • a parent LiveView handling shared layout events and processing and selectively propagating request params to its children (given that nested LiveViews do not receive the request params). it also handles reporting of any errors that any of the three LiveView instances may incur.
  • a nested LiveView handling what I call topics that take place in the main part of the page - it’s essentially delegating all the work to a specialized topic LiveComponent and is there to ensure those run in a separate process than the parent and the second child (nested) LiveView
  • a nested LiveView handling all the modals, also essentially delegating all the work to its specialized modal LiveComponents (which are far from trivial and load their own data from the backend)

The reason for the above is the fact of life that it’s far easier to write and maintain synchronous code that is synchronous in nature - the code that’s fetching data from the backend or mutating the backend state and is therefore far from an instantaneous execution. Putting those otherwise synchronous operations into a single LiveView and making them async (that is achieving the same type of concurrent execution only in a different way) with the sole purpose of having just one LiveView process to me it seemed as an anti pattern so I decided to separate the three parallel sources of synchronous flows.

3 Likes

I think a really good use case for live_render is 3rd party payment forms, e.g. Stripe/Sumup. If you encapsulate the “payment” flow in its own process, so it can use handle_info for async stuff. This is especially helpful if you are using webhooks to update data.

3 Likes

Any documented examples on how to use sticky liveviews? The documentation is rather sparse.

2 Likes

i think docs need to be more updated

There’s an example in Chris McChord’s live_beats app: live_beats/lib/live_beats_web/components/layouts/live.html.heex at master · fly-apps/live_beats · GitHub

And we have a slightly more complex (and still undocumented and quite messy) implementation in Bonfire:

4 Likes

I use it to run an isolated live search bar at the top of my site. I have a huge twitter+facebook clone with many functionality/apps. Think of ambrella app. it even has livestream with membrane and ecommerce market place. I built a search bar that search any entity( such, users, posts, public messages on groups rooms, products in market places, anything in the database that match the regex on the search form will come up. Maybe a liveComponent will do it as well. But I found it better to isolate it from any of my other liveviews for these apps/features.

1 Like

I’m using primarily to isolate a map using mapboxgl that is much better receving JS hooks with data in batches in geojson format from other traditional heex assigns templates.

Since I’m kinda newb with elixir and phx, I felt it was better to isolate from existing components, also understanding better where the failure was in a somewhat complex UI, mixing old phx code (pre 1.7, 1.6, etc), components following v1.7 patterns, including async stuff. I found it hard to find good examples if I was doing fine, basically guessing from the awesome hex.pm docs for the various components.

So I appreciate this topic and the given examples.

2 Likes

In the phoenix_storybook library, I’m using a nested liveview to render the component in isolation. It prevents a component crash from crashing the entire storybook LiveView

https://phoenix-storybook-demo.fly.dev/storybook/components/buttons/dropdown?tab=playground

4 Likes