I updated phoenix_live_view, and deployed, then got 100s of errors reported to Sentry:
LiveView asset version mismatch. JavaScript version 1.0.18 vs. server 1.1.19. To avoid issues, please ensure that your assets use the same version as the server.
if (liveview_version !== this.liveSocket.version()) {
console.error(
`LiveView asset version mismatch. JavaScript version ${this.liveSocket.version()} vs. server ${liveview_version}. To avoid issues, please ensure that your assets use the same version as the server.`
);
}
It’s just a simple log, no logic. Shouldn’t something like window.reload() be invoked when this happens? (Maybe set a flag for what we want the behavior to be.)
Or am I missing something? I see almost nothing in the interwebs about this, yet I know everyone else is updating phoenix_live_view…
In a large app though, what is the practical way to implement this?
Add an on_mount helper in the router for all LiveView’s, and then in the root layout add the logic of showing the banner?
I’m considering adding a PR to update the static_changed? docs to give a bit more realistic details. No one is doing what they propose in a large app with 50+ pages… or maybe that really is what is expected?
def on_mount(:default, _params, _session, socket) do
{:cont, assign(socket, static_changed?: static_changed?(socket))}
end
Add it to MyAppWeb to apply to all LiveViews:
def live_view do
quote do
use Phoenix.LiveView
on_mount MyAppWeb.CheckStaticChanges
In the root template, you can conditionally show something, e.g. a button, to let the user know there’s a new version and they can reload the page. Use the assign in a :if or to set some data attribute and use conditional CSS.
<a
:if={@static_changed?}
href="#"
onclick="window.location.reload()"
>
New version available, click to reload
</a>
Of course the specifics you can decide for your taste or requirements, but those are the building blocks.