Colocated CSS

LiveView v1.2 introduces colocated CSS to allow writing CSS rules in the same file as your regular component code.

To use Colocated CSS, you need to implement the Phoenix.LiveView.ColocatedCSS behaviour. See the module documentation for more details.

Then, you can define it similar to how you would define a colocated hook or Phoenix.LiveView.ColocatedJS:

def table(assigns) do
  ~H"""
  <style :type={MyAppWeb.ColocatedCSS}>
    thead color: {
      ...;
    }
    tbody, tr:hover {
      ...
    }
  </style>
  <table>...</table>
  """
end

Formatting script and style tags

This behaviour allows you to format <script> and <style> tags with third party tooling when running mix format, especially useful if your project uses Phoenix.LiveView.ColocatedHook a lot.

The module documentation contains an example using prettier, which we also use in the LiveView repository itself.

Encoding JS commands to JSON

Phoenix.LiveView.JS structs can now be encoded to JSON for usage in push_event. So now you can do

push_event(socket, "highlight", %{toggle: JS.toggle_class(...)})
// some hook
this.handleEvent("highlight", ({ toggle }) => {
  this.js().execJS(this.el, toggle);
});

while in the past you'd have to render the command in an element attribute and then refer back to it in your hook.

LiveView implements JSON.Encoder and Jason.Encoder automatically. If you use a different library, you can invoke JS.to_encodable/1 manually.

Opting out of debug annotations

You can now opt out of HEEx debug annotations for specific modules by setting

@debug_heex_annotations false
@debug_attributes false

as module attributes in the module that defines your HEEx template. The module attributes override the application configuration:

config :phoenix_live_view,
  debug_heex_annotations: true
  debug_attributes: true

This is useful if you render some templates for different purposes like email where the comments and attributes LiveView adds for debugging in development are a problem.

Here's an example that shows the debug annotations:

<!-- @caller lib/demo_web/live/posts_live/index.ex:19 (demo) -->
<!-- <DemoWeb.CoreComponents.table> lib/demo_web/components/core_components.ex:362 (demo) -->
<table data-phx-loc="363" class="table table-zebra">
  <thead data-phx-loc="364">
    <tr data-phx-loc="365">
      <th data-phx-loc="366">Title</th>
      <th data-phx-loc="367">
        <span data-phx-loc="368" class="sr-only">Actions</span>
      </th>
    </tr>
  </thead>
  ...

The comments can be disabled with debug_heex_annotations and the data-phx-loc attributes with debug_attributes.

Granular configuration for test warnings

LiveView includes some built in checks that run on the DOM when testing. For example, tests will raise an exception if a duplicate ID is detected. We added a new check for forms with phx-change but missing id attribute, because without an id form recovery does not work. Since the severity of that check is different compared to a duplicate ID, LiveView now allows you to configure what should happen for each check:

config :phoenix_live_view, :test_warnings,
  duplicate_id: :warn, # one of :warn, :raise, :ignore
  ...

By default, a form without an ID will now emit a warning. You can opt out of this check per form by setting phx-ignore-missing-id or disable it globally with the :missing_form_id warning option.

See the module documentation or Phoenix.LiveViewTest for more information.

v1.2.0-rc.2 (2026-05-05)

Bug fixes

  • Ensure internal phx-viewport hook does not crash on update if no scroll container is used (#4214)

v1.2.0-rc.1 (2026-05-04)

Enhancements

  • Align Phoenix.Component global attributes list with reference list from MDN (#4207). If you relied on one of the removed attributes, use the include option instead. For example:
    attr :rest, :global, include: ~w(width height)
  • Allow setting id attributes clientside for accessibility with this.js().setAttribute() (#4146)
  • Export getFileURLForUpload helper (#4206)
  • Use moveBefore if available when reordering stream items (#4212)

Bug fixes

  • Handle locks on skipped nodes (#4209)

v1.2.0-rc.0 (2026-04-23)

Enhancements

  • Add Phoenix.LiveView.ColocatedCSS
  • Deprecate the :colocated_js configuration in favor of :colocated_assets
  • Add phx-no-unused-field to prevent sending _unused parameters to the server (#3577)
  • Add Phoenix.LiveView.JS.to_encodable/1 pushing JS commands via events (#4060)
  • HTMLFormatter: Better preserve whitespace around tags and inside inline elements (#3718)
  • HEEx: Allow to opt out of debug annotations for a module (#4119)
  • HEEx: warn when missing a space between attributes (#3999)
  • HTMLFormatter: Add TagFormatter behaviour for formatting <style> and <script> tags (#4140)
  • Add configuration option for :test_warnings and warn for forms without an ID by default (#4128)
  • Performance optimizations in diffing hot path (Thank you @preciz!)

v1.1

The CHANGELOG for v1.1 releases can be found in the v1.1 branch.