How to (Part 2 — Revised): Swap Registration Flow to a Live View With phx_gen_auth — Multi-step form with Live View 0.16+

Geek Culture
Published in
6 min readAug 29, 2021


Metamorphic Early Access registration page. © 2021 Moss Piglet. All rights reserved.


This one is going to be fast, as I’m on the other coastline right now and it’s well past my bedtime.

But, Phoenix Live View 0.16+ dropped a little while ago (in preparation for Phoenix 1.6) and I wanted to update the multi-step form to take advantage of all of the awesomeness in Live View 0.16.

If you are not using Live View 0.16 or Phoenix 1.6+, then hop on over to my original post to see how to easily make a multi-step form with Phoenix and Live View (1.5 and 0.15+, respectively).

Before we dive in, let’s get primed on Live View 0.16:

Live View 0.16 Primer

This update is, quite simply, amazing.

I’ve noticed performance improvements to my code without even changing anything. But, moreover, they added a new HTML engine that found its way over from Marlus Saraiva’s work with the Surface library (and more is expected).

Of all of the great new features in Live View 0.16+, we will be mostly utilizing the .heex templates for this post which enable incredible debugging features for your HTML.

Alright, without further ado, let’s dive in!


To make following along easier, we will assume you have read Part 1, where we swapped the “dead view” over to a Live View for registration. And we’re going to begin with the end of Part 2.

That being said, the same basic prerequisites as the older Part 1 apply with minor changes (Live View 0.16+):

  • You have a working Elixir/Phoenix app setup with the live generator (or add the appropriate code — see the docs).
  • You have installed and setup phx_gen_auth (version 0.6+) using mix phx.gen.auth Accounts Person people (you can substitute other names).
  • You are using phoenix_live_view 0.16+.
  • You are using tailwindcss or understand your own CSS tooling.
  • Optional: You have setup email confirmation with Bamboo.
  • Note 1: Phoenix 1.6+ will include phx.gen.auth generators by default
  • Note 2: If you’ve already followed along with the original Part 2, then this will be a quick update.

Step 0

Okay, let’s look back over our person_registration_live/new.ex from the original Part 2 post:

We’re going to be adding our HTML directly into this file in just a moment, but before we do that, let’s see what our original Part 2 post left us with in our soon-to-be-deprecated templates/person_registration/new.html.leex:


With this as our starting point we will make the update to Live View 0.16+ and utilize the wonderful ~H sigil with the new HTML engine.


This quick guide will see us do the following:

  • deprecate our templates/person_registration/new.html.leex file and consolidate down to one simple Live View file for our registration page
  • keep our router the same as the Part 1 post
  • update our existing render/1 function in our person_registration_live/new.ex file to use ~H and the .heex syntax from Live View 0.16+’s new HTML engine
  • (OPTIONAL) use a running local server session to quickly identify the next line of HTML code that needs updating
  • simplify our codebase while improving our developer experience and application performance

Let’s dig in.

Step 1

Start up a local server session, iex -S mix phx.server, and open your browser to your registration page that you will be editing (this is optional but makes reading the error messages a lot easier, in my opinion).

Then, hop on over to your templates/person_registration/new.html.leex file (yours may be named or organized slightly differently) and copy/paste all of the HTML from there back into your person_registration_live/new.ex file, in an updated render/1 function that will look something like this:

def render(assigns) do
<!-- copy/paste your html here -->
# You updated your old render/1 function that used to point to your now deprecated templates/person_registration/new.html.leex file.

You can now rename your templates/person_registration/new.html.leex file to indicate that it is now deprecated and will soon be deleted (warning: only delete your older file after you’ve tested that your new code is working as it should).

Fantastic! We have now consolidated our sprawling two files into one. You should also now be receiving some error messages in your browser window if you are running a local server session (this is what we want).

Next, we will update our HTML (more specifically, we will update our .leex syntax to the new .heex syntax).

Step 2

Okay, let’s get updating (keep in mind — the effort involved here will vary depending on the size and complexity of your HTML):

  1. If you don’t have a local server session running already, then start one up (it will most likely fail to start at this point but you will now get the error message you need in your console, as well as in your code editor).
  2. Go error-by-error updating your HTML to follow the format outlined in the changelog (you can reference the Live View docs too) — this is where I find it easier to be reading the error message in your browser window alongside your code editor, rather than from the console window.
  3. NOTE: if you receive a slightly dubious error message, it is most likely related to needing to switch an HTML template tag from <%= %> syntax over to the {} syntax.
  4. NOTE: the error messages about missing a closing </div> or ending on this tag when the system expected that tag, are spot on from my experience (and you can use the error line in your code editor alongside that browser error message to really weed out rogue HTML, like extra <div> tags that can be hard to spot).

It’s a little nitty-gritty but you’ll come out the other side so much better, you may even improve your HTML (the new HTML engine doesn’t let you write invalid HTML anymore).

This is what ours, in this example, looks like with the fresh coat of .heex paint:

The things worth noting here are:

  • <.form let={f} for={@changeset} url="#" phx_change="validate phx_submit="save"> and </.form> tags.
  • The replacement of <%= %> from HTML tag attributes to {}. For example, <div class={unless @current_step == 1, do: "hidden"}> ... </div> .

Your final person_registration_live/new.ex file will look something like this with the new ~H sigil render/1 function and .heex template syntax:

And that’s it!

You’ve now got a multi-step form working with Phoenix Live View 0.16+ (and all of the rest of the wonderful improvements that come along with that) — it can do things like tell you what line you forgot a closing </div> or other HTML tag and it keeps you from writing invalid HTML.


Well, that’s it!

We’ve updated our working multi-step form to use the new Phoenix Live View 0.16+ and successfully extended our registration flow from Part 1.

You can easily add more fields following the logic above and build out as many, or as few, steps as you’d like.

If you run into any edge cases with your form steps, then I suggest looking over the addendum in my original Part 2 post.

The ease of upgrade is yet another testament to the tremendous work done by the Elixir/Phoenix teams and community members — thank you!

As always open to improvements and thoughts with a special thanks to Markus and the community at Elixir Forum.


If you haven’t checked it out yet, Metamorphic is live and taking sign ups now for our Early Access launch.

It’s been so awesome to see people signing up and getting excited by the possibility of a better online life — thank you and stay tuned!

❤ Mark



Geek Culture

Creator @ Metamorphic | Co-founder @ Moss Piglet