Jskalc

Jskalc

Phoenix LiveView hot reload has an option to preserve socket state

Sorry if it’s a common knowledge, but it’s something I just learned and wanted to share.

I’ve seen that mind-blowing demo of hot-reload in production recently presented by Chris. So I asked if we could have something like that in development as well: https://twitter.com/jskalc/status/1788293373792596166

It turns out, it’s there already! In your dev.exs Endpoint config add live_reload: notify section and update live_reload: patterns to match this:

# Watch static and templates for browser reloading.
config :my_app, MyAppWeb.Endpoint,
  live_reload: [
    notify: [
      live_view: [
        ~r"lib/my_app_web/core_components.ex$",
        ~r"lib/my_app_web/(live|components)/.*(ex|heex)$"
      ]
    ],
    patterns: [
      ~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
      ~r"lib/my_app_web/controllers/.*(ex|heex)$"
    ]
  ]

Now when you update your live view code, your state will stay intact.

For me it’s a life-changer. I have to admit I wasted so much time without that feature :smiling_face_with_tear: Mostly when working with a bit more complex Live Views with forms or ephemeral state.

Did you know about it? Is it highlighted somewhere in the documentation / installation instructions but I just somehow missed it? :thinking:

Most Liked

chrismccord

chrismccord

Creator of Phoenix

This has been there for months (years?), but we haven’t been certain how we want to recommend usage yet or include by default. It’s the same considerations as production where you can footgun an upgrade into bad state, ie you introduce a new assign in the template and mount, but the running LV doesn’t have it. That said, the LV will blow up, immediately remount and all will be well, so even in most footgun cases you can get back to working state without intervention. All that said, we need to make folks aware of the tradeoffs in the docs, and potentially have it be opt-in as needed vs always enabled for every LV. I definitely understand the QoL improvement this brings in dev – which was the whole reason we added it :slight_smile:

10
Post #4
chrismccord

chrismccord

Creator of Phoenix

It’s harder than that. The example I gave of a missing assign that immediately crashing and remounts is the happy path which recovers to a good state, but there are other cases where the app can enter a bad state and not crash (ie you setup pubsub subscriptions or other stateful bits in mount that don’t happen for exisitng process, or you have timers that need to fire, or you had timers that were firing but you removed them and their handle_info clauses and they blow up the process at some point in the future. There’s not try/catch here that saves you. It’s less about transient errors which aren’t a big deal in dev and more about breaking apps in confusing ways, especially for folks that don’t really know what’s going on/why. So I think a non remount live reload is best opt-in where folks could add matches in their config for specific files, or some similar mechanism. Of course it’s fine to go all in and manually refresh as necessary if you know what’s going on, but as a general default it’s tricky to allow users to get into confusing or bad state that shouldn’t be possible to happen.

Jskalc

Jskalc

Thanks for explaining! I had a feeling it’s not a new thing.

It gave me a huge productivity boost. Considering how much engagement my tweet received, it was also useful to others.

I understand your reasoning about being careful to set it as a default, but it would be great to raise awareness. I see these hopefully reasonable options:

  1. Set it as a default, and maybe automatically catch re-render errors when hot-updated with missing assign, so console won’t be cluttered by transient errors
  2. Include commented out in the generated config, with a short explanation what it would do.
  3. Mention it either in the installation instructions or LiveReload docs
  4. Make it an CLI option in phx.new generator?

Personally I’d love to see 1) happen, or 2) if 1) is too dangerous. I might help with a PR if needed.

PS. Thanks to that feature, I was able to achieve amazing DX with my up-and-coming LiveVue library (LiveSvelte but for Vue + Vite). Updates both in JS and EX files are reflected instantly, keeping the state intact. It feels like cheating :smiling_face_with_three_hearts:

cmo

cmo

With the liveviews under notify do you need to remember to manually refresh when you change how state is determined?

I have my CSS and surface templates under notify, which I saw in the surface slack recently, but not my liveviews. Hadn’t heard of the feature before that.

Jskalc

Jskalc

I think under the hood it uses Erlang code updates.

State stays intact, so it only re-renders HTML and sends diff to the browser. It’s the same as you might know from JavaScript hot reload, eg with Vite.

I must admit, for me it’s kinda a big deal.

Where Next?

Popular in Guides/Tuts Top

niku
I have published an elixir project with using Travis CI. I would like to share some tips & thoughts that I was getting through this ...
New
slouchpie
Warmest greetings, comrades. I recently started using :dns_cluster (GitHub - phoenixframework/dns_cluster: Simple DNS clustering for dis...
New
hauks96
Hello everyone, I created a deployment tutorial for Phoenix applications with Kubernetes (microk8s) a few months back with the goal of s...
New
eclark
I’ve been working on a phoenix project lately and I wanted to use the latest versions of everything. Webpack 5 had some breaking changes ...
New
hlx
Typed my very first blog post ever, hope it will help some people https://henricus.xyz/roll-your-own-email-password-authentication-with...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
jshprentz
Geoffrey Lessel’s 2019 book, Phoenix in Action, was written for Phoenix 1.4. I found that the book’s code examples did not match the cur...
New
f0rest8
Hi, TLDR: form attribute set on the input fields and button submit. I just wanted to share a solution I discovered when making live inl...
New
AstonJ
With a few questions relating to this recently, I wonder if it might help having a thread where we share how we’ve set up Elixir/Erlang/P...
New
AstonJ
..or as and when you can think of one :icon_cool: This thread my also be of interest: What took you way too long to figure out? :003:
New

Other popular topics Top

SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

We're in Beta

About us Mission Statement