Phoenix LiveView 1.2 Release Notes

Phoenix LiveView 1.2 introduces the ability to colocate CSS directly within HEEx templates, mirroring the previously released colocated JavaScript functionality. This update aims to streamline component development by keeping styles and logic in a single location while maintaining compatibility with standard CSS build pipelines.

Colocated CSS in HEEx Templates

Phoenix LiveView 1.2 allows developers to define styles directly inside HEEx templates using a <style> tag with a specific :type attribute.

Implementation and Build Pipeline

Styles defined with the :type attribute (e.g., <style :type={MyApp.ColocatedCSS}>) are extracted at compile time into a dedicated phoenix-colocated folder within the _build directory. These extracted styles are then processed by the project's existing CSS bundler, such as Tailwind or Esbuild, ensuring that colocated styles follow the same production pipeline as global CSS.

CSS Scoping and the @scope Rule

To prevent colocated styles from leaking into other components, LiveView leverages the modern CSS @scope rule. This is achieved by annotating the rendered HTML to define boundaries:

  • Root Tags: A special phx-r attribute is added to the outermost elements of a template to act as a limit selector.
  • Component Identification: Root elements of components using scoped CSS receive a unique phx-css-* attribute.

This allows for CSS rules such as @scope ([phx-css-foo]) to ([phx-r]) { p { font-weight: bold; } }, which ensures that only paragraphs within a specific component are affected.

Note on Browser Support: As of June 2026, the @scope rule is not universally supported across all browsers. Consequently, LiveView 1.2 does not enable scoping by default. Instead, it provides a @behaviour that allows developers to implement their own custom scoping strategies or opt-in to the @scope implementation for early adoption.

To enable the root tag attribute, the following configuration is required:

config :phoenix_live_view,
  root_tag_attribute: "phx-r"

HEEx Compilation Overhaul

The introduction of colocated CSS necessitated a fundamental change in how HEEx templates are compiled. The compilation process has been split into two distinct steps: tokenization and parsing.

This architectural change allows LiveView to handle macro components (like colocated CSS and JS) without increasing the complexity of the general compilation process. Additionally, this refactor eliminated code duplication that previously existed between template compilation and formatting.

Additional Improvements in 1.2

LiveView 1.2 includes several quality-of-life updates for developers:

  • Custom Tag Formatting: Developers can now implement the Phoenix.LiveView.HTMLFormatter.TagFormatter behaviour to format <script> and <style> tags in HEEx using external tools like Prettier.
  • Automatic JS Struct Encoding: Phoenix.LiveView.JS structs are now automatically encoded when sent via push_event if using Jason or the built-in JSON module. Manual encoding is still possible via JS.to_encodable/1.
  • Configurable Debug Annotations: The @debug_heex_annotations and @debug_attributes module attributes now allow for per-module configuration of HEEx debug annotations.
  • Test Configuration: Test warnings can now be configured by category.
  • Documentation: The JavaScript client now has its own dedicated documentation.

Community Perspectives

While the release is generally welcomed, some developers have expressed caution regarding the trend toward colocation. One contributor noted that while convenient, colocating JS and CSS could potentially lead to maintenance challenges similar to older versions of Ruby on Rails:

"It reminds me of Rails 2.x where it became almost impossible to debug, or fix front end code that used rjs... because disparate snippets of JS were littered throughout your code base in files that were hard to find."

Conversely, other users highlighted the efficiency of the Phoenix approach compared to modern JavaScript frameworks, noting that the "backend-heavy" SPA model is simpler to maintain and faster to reason about than complex frontend build chains.

Sources