Live reloading stopped working (phoenix 1.8-rc1, elixir 1.18, otp 27)

Live reloading stopped working (phoenix 1.8-rc1, elixir 1.18, otp 27)

For some reason, my live reloading isn’t working anymore and I have no idea why. I upgraded my phoenix app from 1.7 to 1.8-rc1. Somewhere along the way, I think its related, my live reloading stopped working.

Versions

  • phoenix: 1.8-rc1
  • elixir 1.18.3
  • erlang 27.0.3

Description

First, I checked to make sure that live debugger is connecting:

if (process.env.NODE_ENV === "development") {
  window.addEventListener(
    "phx:live_reload:attached",
    ({ detail: reloader }) => {
      console.log("🦠 'reloader attached':", "reloader attached");

Which returns 🦠 'reloader attached': reloader attached in the browser, so we are all good there.

However, I did notice that no logs are streamed to the browser even though this is set up correctly:

config :my_app, MyAppWeb.Endpoint,
  live_reload: [
    web_console_logger: true,
    patterns: [
      ~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
      ~r"priv/gettext/.*(po)$",
      ~r"lib/my_app_web/(controllers|live|components)/.*(ex|heex)$"
    ]
  ]

As you can see from the snippet above I did try to specify another path because I thought that this might be the issue but it made no difference.

What is also strange is that any time I change a file all I see is this in the console:

Done in 2ms

However, I liveview doesn’t refresh the page, I see no re-compilation (was that Done message the recompilation?).

other things I have tried

i tried the things listed below but didn’t have any success:

  1. upgrade/downgrade to different elixir version
  2. upgrade/downgrade to other phoenix 1.8 rc version
  3. try a different file watching type (like :fs_event)
  4. checked and made sure that my inotify allows more watchers

Does anybody have any idea what could cause this behaviour? I did try to reboot my computer and it appeared to work again, so perhaps it’s a local issue? I’m running on ubuntu 24.04.

This line is incorrect - it will only reload files in the root my_app_web folder, not any subdirectories. (And the wildcard needs to be fixed)

It should be eg. ~r"lib/my_app_web/**/.*(ex|heex)$".

4 Likes

I’m sry my post was confusing. It also didn’t work with the commented out line. I updated the post.

The actual regex that worked was this: ~r{lib/my_app_web/.*\.(?:ex|heex)$}

Hi there,
I am having the maybe exact same problem.
Suddenly the code reload mechanism stopped working - I was working in a totally different and unrelated corner of my app.
i upgrader then all libs to latest greatest, did clean and recompile everything.

  • phoenix_live_view 1.1.11
  • phoenix_live_reload 1.6.1
  • Elixir 1.18.3 (compiled with Erlang/OTP 27)

I double checked the patterns, but I have pretty much those from the generator and those worked fine in the past:

 patterns: [
      ~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
      ~r"priv/gettext/.*(po)$",
      ~r"lib/portal_web/(?:channels|common|components|controllers|live|router)/?.*\.(ex|heex)$"
    ]

In the mix project I have listeners: [Phoenix.CodeReloader] set.

Also in the endpoint this is set:

  # Code reloading can be explicitly enabled under the
  # :code_reloader configuration of your endpoint.
  if code_reloading? do
    socket "/phoenix/live_reload/socket", Phoenix.LiveReloader.Socket
    plug Phoenix.LiveReloader
    plug Phoenix.CodeReloader
    plug Phoenix.Ecto.CheckRepoStatus, otp_app: :portal
  end

any idea?

When you load the page you should have 2 open websockets. One is for phoenix and the other one is for hot code reloading, do you see those?

ah, good hint. No.
I see:

  • ws://localhost:4000/live/websocket and
  • ws://localhost:4000/socket/websocke

the second one is a custom socket created by me… so the reloader socket seems to be missing.
And I guess there should be also be an iframe in the client… which is gone… hmmm…

There is an issue that if you move the <body> tag out of root.html.heex it will break your reloader:

Could that be your issue?

1 Like

Oh !!!

@FlyingNoodle that might be the case - because that’s actually exactly what I did… I refactored out the body from the root template…
Iwill rewind and check…

Okay, it works again. But the behavior was a bit strange and a bit random to fix it.

I guess the cause was the removal of the tag from the root payout, mentioned by @FlyingNoodle .

  • I fixed that and moved it back to the root template. but still it did not work. no iframe no wet-socket
  • Then I recognized that I had split the config up like this:
config :portal, MyApp.Endpoint,
  # Binding to loopback ipv4 address prevents access from other machines.
  # Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
  http: [ip: {0, 0, 0, 0}, port: 4000],
  http_options: [
    log_exceptions_with_status_codes: 0..999,
    log_protocol_errors: :verbose,
    log_client_closures: :verbose
  ],
  check_origin: false,
  code_reloader: true,
  debug_errors: true,
  ...
  watchers: [
    esbuild: {Esbuild, :install_and_run, [:portal, ~w(--sourcemap=inline --watch)]},
    tailwind: {Tailwind, :install_and_run, [:portal, ~w(--watch)]}
  ]

...

config :portal, MyAppWeb.Endpoint,
live_reload: [
  web_console_logger: true,
  patterns: [
      ~r"priv/static/(?!uploads/).*(js|css|png|jpeg|jpg|gif|svg)$",
      ~r"priv/gettext/.*(po)$",
      ~r"lib/portal_web/(?:controllers|live|components|common|router)/?.*\.(ex|heex)$"
  ]
]

Then I unified this, so live_reload is part of the first (and then only) config block

… and then it worked again…

1 Like