Starter Guide for HEEx Templates

The HTML EEx templates is the built-in templating engine for Phoenix framework. This reference is helpful for people familiar with templating languages like Nunjucks or Jinja.

We’ll be covering the following:

Using Phoenix LiveView, we can render a view either by defining render/1 function, or placing template code in a file.

For simplicity, let’s assume the module defines render/1 function, which returns a HEEx template, defined using a ~H sigil.

def render(assigns) do
template content here


The assigns parameter can be either an Elixir Keyword or a Map, accessible within template code.


<p><%= @name %></p>

Accessing the value using @ when the value is undefined ends up in an exception. So, in case you need to provide a fallback in the template, you have to access the value through assigns, and supply a fallback.

<p><%= assigns[:name] || "Untitled" %></p>

HEEx templates comes with HTML validation and shorter interpolation syntax of attributes. You can provide a value to HTML attributes using key={value} syntax. HEEx will remove the attribute from rendered HTML when the value is false.

<div data-user-state={@state}> ... </div>
<div class={@classes}>
<p>Hello <%= @username %></p>

…will magically render to:

<div class="highlight bold">
<p>Hello joe</p>


If… else…

<%= if @state == "new" do %>
<p>Newly joined.</p>
<% end %>
<%= if @state == "new" do %>
<p>Newly joined.</p>
<% else %>
<% end %>


Consider a user data passed down through assigns as:

assign(conn, :users,
users: [
%{name: 'Jamie Houston', age: 20},
%{name: 'Barbara John', age: 23}

…you can loop over the array using:

<%= for user <- @users do %>
<div class="name"><%= %></div>
<div class="age"><%= user.age %></div>
<% end %>


To replicate the function of include tag from Nunjucks and Jinja, to render another template file, you can use render/2 within templates

<%= render "another-template.html", assigns %>


HEEx, by default, escape all HTML content. You can use raw to allow unescaped HTML.

<%= raw "<hello/>" %>


<%# This is a comment. %>

<%# And,
...this is a multiline comment.