Phoenix Live Components — A Quick Overview

Juli.Smz
Elixir Labs
Published in
3 min readSep 2, 2022
Creative Commons (CC)

This article is a quick overview of the different types of LiveView components. I will talk about the various ways to use them related to the templating, but to keep it reader-friendly I will skip deep concepts like passing variables (assigns) and event handling, among others.

To start, and speaking easy, we could aggregate the LiveView components into 4 types.

  1. Components with render.
  2. Components with a template.
  3. Components with slots (slots components).
  4. Function components.

Locations

The common location to store components is on the yourproject_web/live folder. I usually have a default_live subfolder to store common template stuff like navigation, hero, etc. In this case, I’m going to work with a navigation bar, showing the below-listed options. As navigation is something global, I have it located on acme_web/live/default_live/navigation_component.ex

1)Components with render

At least, a component must have the render()/1 function:

If you are not familiar with the sigils (~H) I recommend reading this.

~H requires an HTML element as root. You can’t do this:

Then, on your html, you have to call this component like this:

That’s it! What if we wanted to separate HTML from logic? If you are like me, you are probably not happy putting HTML into a logic function. (Perl alert!)

2. Components with a template.

If we prefer to separate the HTML from the logic of the controller, we must follow these steps:

  1. Eliminate the render function.
  2. Create a new file on the same location, with the same name, but with .html.heex extension. We get test_component.html.heex.
  3. Put the HTML there…

That’s all! Phoenix will automagically understand that if there is no render() function declared, it has to find a file with the same name, but heex extension.

This won't even require an example code! And you might be wondering “What do I want a component for?”. Well, take into account that on the component file you will put all the event handlers, stateful control, and so on.

3. Components with slots (slots components).

I like this because it reminds me of old times with Symfony 1.4. In order to use this option, we have to say “hi” again to the render() function.

The idea behind this hybrid method is to place part of the HTML on the component render() and part on the template. This time, you have to open and close the component tag to encompass the inner slot.

Let’s see how it´s done!

And on the template:

As you could see, we set global tags outside, and dynamic elements on the template. render_slot()/1 will be your friend here.

From LiveView HexDocs:

The templates rendered inside the components can use live_path() and live_redirect() functions!!

4. Function components.

Such a name, what’s this??

On the one hand, is a way to “name” a component. You might have noticed that we have been using<.live_component tag>, but you can call it any way you want.

Function components don’t use their own files, this means we can delete navigation_component.ex file, since the code is moved to the main logic template. For example, if you include the component on acme_web/live/default_live/default.html.heex you should create a function on acme_web/live/default_live/default.ex called navigation().

Now on the template, you can use <.navigation> instead of<.live_component>

Now on the template, we can use <.navigation> instead of <.live_component>

https://gist.github.com/somoza/2c312078586c77880f0c2d0e054d3b3f.js

On the other hand… and now you know all the variants, this is very useful to replace things like this:

By this:

Conclusion:

Depending on our needs, we can find one variant more useful than another. Knowledge is power and now you have the choice of which one to use.

I recommend you learn deeper concepts like a stateful, source of truth, event handling, preloading, update, etc from the original documentation.

--

--