🤨 What do you name your own `link` component in a Phoenix codebase?

Notes

I like that Phoenix comes with a <.link> component out of the box. It handles a lot for us: live patching, live-session navigation, and regular page visits.

But I typically want my own link-like component. And I always struggle to find a name for it. (<.my_app_link> is just dreadful 🤮)

Why have my own component?

I typically want to have consistent visual styles in my app without having to add the same class everywhere.

So, what’s a good name?

Lately, I’ve settled on creating an <.a> component:

  attr :class, :string, default: nil
  attr :rest, :global, include: ~w(patch href navigate)
  slot :inner_block, required: true

  def a(assigns) do
    ~H"""
    <.link class={["underline text-blue-500", @class]} {@rest}>
      <%= render_slot(@inner_block) %>
    </.link>
    """
  end

We define two attributes:

  • class in case we want to add or override the standard CSS, and
  • rest which allows us to forward all regular HTML attributes to the <.link> component. But note we also include patch, href, and navigate, since those are non-standard, but we want to forward them to the <.link> component.

Finally, we render the <.link> component with the @class and @rest assigns, and we render the @inner_block slot.

Simple, and now the rest of our codebase can use <.a>.

P.S. I think it’s funny that we’re back to an “anchor”. So, the <.a> component wraps a <.link> component which wraps an <a> tag. 🤷

NOTE: the video shows @rest in the anchor component. It should be {@rest} (as the notes above show correctly). Without the brackets, HEEX won’t evaluate the @rest assign. Just an oversight in my hasty implementation for the video.

Want the latest Elixir Streams in your inbox?

    No spam. Unsubscribe any time.