Ethan Gunderson

TIL: String layout options deprecated in LiveView 18.3

If you're upgrading an existing Phoenix application to LiveView 18.3 you might run into this compilation warning

warning: passing a string as a layout template in use options is deprecated, please pass an atom, such as :live instead of "live.html"
  (phoenix_live_view 0.18.3) lib/phoenix_live_view/utils.ex:154: Phoenix.LiveView.Utils.normalize_layout/2
  (phoenix_live_view 0.18.3) lib/phoenix_live_view.ex:493: Phoenix.LiveView."MACRO-__before_compile__"/2
  (elixir 1.13.4) src/elixir_dispatch.erl:202: :elixir_dispatch.expand_macro_fun/7
  (elixir 1.13.4) src/elixir_dispatch.erl:189: :elixir_dispatch.expand_require/6
  (elixir 1.13.4) src/elixir_dispatch.erl:112: :elixir_dispatch.dispatch_require/7
  (elixir 1.13.4) src/elixir_module.erl:390: :elixir_module.expand_callback/6

Which is really frustrating because the stacktrace does not give you the location of the offending line. For my application, the issue was in the application web module.

def live_view do
  quote do
    use Phoenix.LiveView,
      layout: {GleanWeb.LayoutView, "live.html"} # <- Crusty old way
      layout: {GleanWeb.LayoutView, :live} # <- New way



This deprecation can also cause odd Dialyzer errors. In my router I have a pipeline that looks something like this:

pipeline :unauthenticated do
  plug(:put_root_layout, {GleanWeb.LayoutView, "unauthenticated.html"})
  plug(:put_layout, false)

Which causes this Dialyzer error.

Function unauthenticated/2 has no local return.

The fix is to replace the string with an atom.

plug(:put_root_layout, {GleanWeb.LayoutView, :unauthenticated})

Subscribe to my blog via email or RSS feed.

#elixir #phoenix #til