Alias `Phoenix.LiveView.ColocatedHook` in new apps like `Phoenix.LiveView.JS`

The Phoenix template for new apps generated with phx.new sets an alias that allows using JS commands in HEEx templates and other places conveniently without the full module name. For instance, most of the time we can write

<button phx-click={JS.show(to: "#modal", transition: "fade-in")}>
  show modal
</button>

instead of

<button phx-click={Phoenix.LiveView.JS.show(to: "#modal", transition: "fade-in")}>
  show modal
</button>

ColocatedHook (and ColocatedJS) would benefit from a similar alias, making colocated hooks less verbose to use.

With the alias we could write:

<script :type={ColocatedHook} name=".PhoneNumber">
// ...
</script>

Considerations

  • The impact on the existing eco-system: ColocatedJS and ColocatedHook were released recently in Phoenix LiveView 1.1. Adding the alias would simplify future projects, with no impact to existing usage with the fully qualified module path.
  • The impact on learning: It would make ColocatedJS and ColocatedHook as easy to use as JS commands in HEEx templates.
  • Whether your suggestion is easily implemented or inline with the state of Phoenix as it is today: The implementation is a simple template update. New apps already depend on LiveView 1.1, so the new modules are guaranteed to be available.
  • Whether your suggestion would benefit Phoenix or the community as a whole: I’m biased. But having setup the alias in my current project, I find the less verbose template code clear enough, no ambiguity. In fact, I had once copied the example in the release notes just to realize it didn’t compile (when I didn’t have the alias).

Implementation

If accepted, I can provide a PR. The diff:

diff --git a/installer/templates/phx_single/lib/app_name_web.ex b/installer/templates/phx_single/lib/app_name_web.ex
index 06c762714..e90288a8c 100644
--- a/installer/templates/phx_single/lib/app_name_web.ex
+++ b/installer/templates/phx_single/lib/app_name_web.ex
@@ -88,6 +88,8 @@ defmodule <%= @web_namespace %> do
       import <%= @web_namespace %>.CoreComponents
 
       # Common modules used in templates
+      alias Phoenix.LiveView.ColocatedHook
+      alias Phoenix.LiveView.ColocatedJS
       alias Phoenix.LiveView.JS
       alias <%= @web_namespace %>.Layouts
 
diff --git a/installer/templates/phx_umbrella/apps/app_name_web/lib/app_name.ex b/installer/templates/phx_umbrella/apps/app_name_web/lib/app_name.ex
index d8b1f9543..87a06fc35 100644
--- a/installer/templates/phx_umbrella/apps/app_name_web/lib/app_name.ex
+++ b/installer/templates/phx_umbrella/apps/app_name_web/lib/app_name.ex
@@ -88,6 +88,8 @@ defmodule <%= @web_namespace %> do
       import <%= @web_namespace %>.CoreComponents
 
       # Common modules used in templates
+      alias Phoenix.LiveView.ColocatedHook
+      alias Phoenix.LiveView.ColocatedJS
       alias Phoenix.LiveView.JS
       alias <%= @web_namespace %>.Layouts

An optional accompanying change would be updating the LiveView docs to use the non-fully qualified module name in examples.

I was thinking about this, but decided to not alias by default because I don’t think it’s used so frequently (especially ColocatedJS). Maybe I’m wrong, but I’d like to get more feedback on this.

What we can definitely do is add a tip to the docs to set the alias in case people use it more often in their projects!

I agree regarding frequency. I certainly have way more use of JS commands than I ever expect to have ColocatedHook (and ColocatedJS).

What I realized was that even for a single use the fully qualified module name was verbose and harder to remember. Considering those names are so specific (because of the “colocated” prefix), I decided they are too unlikely to conflict with anything in my project and went with the aliases in myapp_web.ex.

Let’s hear who else is using the new goodies in their projects :slight_smile: