close icon
daily.dev platform

Discover more from daily.dev

Personalized news feed, dev communities and search, much better than whatโ€™s out there. Maybe ;)

Start reading - Free forever
Start reading - Free forever
Continue reading >

Phoenix LiveView Tutorial: Getting Started

Phoenix LiveView Tutorial: Getting Started
Author
Nimrod Kramer
Related tags on daily.dev
toc
Table of contents
arrow-down

๐ŸŽฏ

Learn how to build interactive, real-time web applications with Phoenix LiveView using Elixir and Phoenix. Get started with key components, core concepts, best practices, and tips for better LiveView apps.

Phoenix LiveView is a powerful tool for building interactive, real-time web applications using Elixir and Phoenix. Here's what you need to know:

  • Purpose: Create fast, scalable web apps with real-time updates
  • Key Components:
    • mount function: Sets up initial state
    • handle_event function: Responds to user actions
    • render function: Displays updated view

Quick Setup:

  1. Install Elixir and Phoenix
  2. Create a new Phoenix project
  3. Add LiveView to your project
  4. Build your first LiveView module

Core Concepts:

  • DOM element bindings (e.g., phx-click)
  • Form handling and file uploads
  • Page navigation without reloading
  • Function components and LiveComponents

Best Practices:

Feature Phoenix Phoenix LiveView
Updates Full page reload Real-time, partial updates
Best for Traditional web apps Interactive, real-time apps
Process New process per request One process per WebSocket

This tutorial will guide you through setting up and using Phoenix LiveView to create dynamic, responsive web applications.

2. Before You Start

2.1 Installing Elixir and Phoenix

Elixir

To begin with Phoenix LiveView, you need Elixir and Phoenix on your computer. Here's how to set them up:

1. Install Elixir

2. Install Phoenix

  • Open your terminal
  • Run this command: mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez

To check if everything is set up correctly, create a new Phoenix project:

  • In your terminal, type: mix phx.new my_app (replace "my_app" with any name you like)

2.2 What You Need to Know

To use Phoenix LiveView well, you should understand:

Topic Description
Elixir basics Data types, functions, modules
Phoenix framework Routing, controllers, templates
Web development HTTP requests, responses, HTML, CSS, JavaScript

If you're new to Elixir or Phoenix, start with these learning resources:

These will help you build a good base before you start with LiveView.

3. Creating a New Phoenix Project

3.1 Setting Up Your Project

Let's create a new Phoenix project for your LiveView application. Open your terminal and run:

mix phx.new my_app

Replace my_app with your preferred name.

This command creates a new directory with the basic Phoenix structure:

Directory Purpose
lib Application code
test Tests
priv Static assets and private files
config Application configuration

3.2 Adding LiveView to Your Project

To use LiveView, add it to your project:

  1. Open mix.exs and add this line to the deps function:
defp deps do
  [
    #...
    {:phoenix_live_view, "~> 0.17.5"},
    #...
  ]
end
  1. Install the dependency:
mix deps.get
  1. Set up LiveView in config/config.exs. Add these lines to the config function:
config :my_app, MyAppWeb.Endpoint,
  live_view: [
    signing_salt: "your_secret_salt"
  ]

Replace your_secret_salt with a secret of your choice.

You've now set up LiveView in your Phoenix project. Next, we'll look at how LiveView works.

4. LiveView Basics

4.1 How LiveView Works

LiveView helps build interactive web apps that update in real-time. Here's how it works:

  1. User does something (like clicking a button)
  2. This action changes the app's state
  3. LiveView updates the relevant parts of the web page
  4. The browser shows these updates without reloading the whole page

This process makes web apps feel quick and responsive.

Step Description
1. Event User interacts with the app
2. State Change App's data updates
3. Re-render LiveView updates affected parts
4. Browser Update Changes appear on screen

4.2 Main LiveView Functions

LiveView uses three key functions:

Function Purpose
mount/3 Sets up the initial state and view
handle_event/3 Responds to user actions
render/1 Shows the updated view

These functions work together to create a smooth, interactive experience for users.

5. Building Your First LiveView

5.1 Creating a LiveView Module

To start your first LiveView, make a LiveView module. This module has functions that control how your LiveView works. Here's how to create one:

defmodule MyAppWeb.ThermostatLive do
  use Phoenix.LiveView
  #...
end

5.2 Writing the render Function

The render/1 function shows the HTML for your LiveView. It takes one argument, assigns, which is a map of values for the template.

Here's an example:

def render(assigns) do
  ~H"""
  Current temperature: <%= @temperature %>ยฐF
  <button phx-click="inc_temperature">+</button>
  """
end

This function shows the current temperature and a button to increase it.

5.3 Using ~H for HTML Templates

The ~H sigil helps you write HTML templates. It uses a syntax like HTML.

Example:

~H"""
<div>
  <h1>Hello World!</h1>
  <p>This is a paragraph of text.</p>
</div>
"""

This creates a div with an h1 and a p element inside.

Function Purpose Example
use Phoenix.LiveView Sets up LiveView in your module use Phoenix.LiveView
render/1 Shows HTML for your LiveView def render(assigns) do ... end
~H sigil Writes HTML templates ~H"""<div>...</div>"""

6. Setting Up Initial State

6.1 The mount Function Explained

The mount/3 function in Phoenix LiveView sets up the starting state of your LiveView. It runs when the LiveView first loads and takes three inputs:

Input Description
params A map of parameters sent to the LiveView
session The current session
socket The LiveView socket

Here's a basic example:

def mount(params, session, socket) do
  {:ok, assign(socket, temperature: 20)}
end

This sets the starting temperature to 20 degrees.

6.2 Setting Up Starting Data

You can get data from a database or API in the mount/3 function. Here's how to do it with Ecto:

def mount(params, session, socket) do
  temperature = Repo.get_by(Temperature, id: 1)
  {:ok, assign(socket, temperature: temperature.value)}
end

This gets the temperature with ID 1 from the database and sets it in the socket.

You can also handle errors in mount/3. For example:

def mount(params, session, socket) do
  try do
    temperature = Repo.get_by(Temperature, id: 1)
    {:ok, assign(socket, temperature: temperature.value)}
  rescue
    e in Ecto.NoResultsError ->
      {:ok, assign(socket, temperature: 20)}
  end
end

If the database doesn't have a temperature with ID 1, this sets a default of 20 degrees.

Function Purpose
mount/3 Sets up starting state
assign/2 Adds data to the socket
Repo.get_by/2 Gets data from the database

These tools help you set up your LiveView with the right starting data.

7. Responding to User Actions

7.1 Using handle_event

The handle_event/3 function in Phoenix LiveView responds to user actions. It takes three inputs:

Input Description
event Name of the event
params Map of parameters sent with the event
socket LiveView socket

Here's a basic example:

def handle_event("click", %{"id" => id}, socket) do
  # Handle the click event
  {:noreply, socket}
end

This function runs when a user clicks a button with the event name "click".

7.2 Changing State After User Input

To update the LiveView state after user input, use the assign/2 function:

def handle_event("text-entered", %{"text" => text}, socket) do
  {:noreply, assign(socket, text: text)}
end

This updates the text field in the socket when the user enters text.

You can also send events to the client with push_event/2:

def handle_event("text-entered", %{"text" => text}, socket) do
  {:noreply, push_event(socket, "text-entered", %{text: text})}
end

This sends an event to the client with the name "text-entered" and the entered text.

Function Purpose
handle_event/3 Responds to user actions
assign/2 Updates LiveView state
push_event/2 Sends events to the client

Example:

Let's say you're making a LiveView for users to enter their name and age. When they click "Submit", you want to update the LiveView state:

def handle_event("submit", %{"name" => name, "age" => age}, socket) do
  {:noreply, assign(socket, name: name, age: age)}
end

This code updates the LiveView state with the entered name and age when the user clicks "Submit".

sbb-itb-bfaad5b

8. Using LiveView Bindings

8.1 What Are DOM Element Bindings?

DOM element bindings in Phoenix LiveView let you connect events to HTML elements. This helps you respond to user actions like clicks or typing, and update your LiveView state.

Bindings use the phx- prefix followed by the event name. For example, phx-click connects a click event to an element. These bindings trigger events on the server, which can then change the LiveView state.

8.2 Common Binding Examples

Here's a table of common bindings:

Binding What it does
phx-click Responds to clicks
phx-submit Responds to form submissions
phx-keyup Responds when a key is released
phx-keydown Responds when a key is pressed
phx-blur Responds when an element loses focus
phx-focus Responds when an element gains focus

You can use these bindings on different HTML elements. For example:

<button phx-click="submit">Submit</button>

This code makes the button trigger a "submit" event on the server when clicked.

You can also use bindings on larger elements:

<div phx-window-keyup="handle-keyup">
  <input type="text" />
  <button>Submit</button>
</div>

This code makes the whole div respond to key releases, triggering a "handle-keyup" event on the server.

9. Working with Forms

9.1 Building and Processing Forms

Forms are key in web apps. Phoenix LiveView makes form handling easy. Here's how to build and process forms in LiveView:

To create a form, use the form function from Phoenix.HTML. This function needs:

  • The form's submit URL
  • The method (like :post or :get)
  • Any extra form attributes

Here's a simple form example:

def render(assigns) do
  ~H"""
  <form phx-submit="submit">
    <input type="text" name="name" />
    <input type="submit" value="Submit" />
  </form>
  """
end

This form has a text input and a submit button. The phx-submit attribute sets the event for form submission.

To handle the form data, use the handle_event function in your LiveView module:

def handle_event("submit", %{"name" => name}, socket) do
  # Process the form data here
  {:noreply, socket}
end

This function takes the event name and form data as inputs. It processes the data and returns a tuple.

9.2 Handling File Uploads

File uploads in LiveView need a bit more work, but it's not too hard. Use the Phoenix.LiveView.Upload module for this.

Here's how to handle a file upload:

def render(assigns) do
  ~H"""
  <form phx-submit="upload">
    <input type="file" name="file" />
    <input type="submit" value="Upload" />
  </form>
  """
end

def handle_event("upload", %{"file" => file}, socket) do
  # Process the file upload here
  {:noreply, socket}
end

This form has a file input and a submit button. The upload event handles the file data.

Step Description
1 Create a form with a file input
2 Set up an event handler for the upload
3 Process the file data in the handler
4 Return a tuple to show the event is handled

10. Page Navigation

10.1 Changing Pages Without Reloading

Phoenix LiveView lets you change pages without reloading the whole page. This makes your app feel faster. You can use the live_redirect function to do this.

Here's how to use live_redirect:

def handle_event("go_to_next_page", _, socket) do
  {:noreply, live_redirect(socket, to: "/next_page")}
end

This code sends the user to "/next_page" without reloading the page when the "go_to_next_page" event happens.

10.2 Updating vs. Loading New LiveViews

When moving between pages in a LiveView app, you can:

  1. Update the current LiveView
  2. Load a new LiveView
Action When to Use How It Works
Update current LiveView Small changes Changes data or layout of current page
Load new LiveView Big changes Shows a completely new page

To update the current LiveView:

def handle_event("update_page", _, socket) do
  {:noreply, update(socket, :page_data, &Map.put(&1, :new_data, "new value"))}
end

This code changes the page_data when the "update_page" event happens.

To load a new LiveView, use live_redirect as shown earlier.

Choose between updating and loading based on how much the page needs to change. For small changes, update the current LiveView. For big changes, load a new one.

11. Organizing Your Code

11.1 Using Function Components

As your Phoenix LiveView app grows, it's important to keep your code tidy. Function components help with this. They are small, reusable pieces of code that do specific tasks.

To make a function component in Phoenix LiveView, use the defcomponent macro:

defcomponent MyComponent do
  def render(assigns) do
    ~H"""
    <div>
      <h1>Hello, World!</h1>
    </div>
    """
  end
end

You can use this component in your LiveView templates like this:

~H"""
<div>
  <%= MyComponent.render(%{}) %>
</div>
"""

Function components help you:

  • Break big templates into smaller parts
  • Reuse code in different parts of your app

11.2 Working with LiveComponents

LiveComponents are special function components for Phoenix LiveView apps. They can update on their own when your app's data changes. This makes them good for showing real-time updates.

To make a LiveComponent, use the def live_component macro:

def live_component MyLiveComponent do
  def render(assigns) do
    ~H"""
    <div>
      <h1>Hello, World!</h1>
    </div>
    """
  end

  def update(assigns, socket) do
    # Update the component state here
  end
end

You can use this LiveComponent in your templates like this:

~H"""
<div>
  <%= MyLiveComponent.render(%{}) %>
</div>
"""

Here's a table comparing Function Components and LiveComponents:

Feature Function Components LiveComponents
Updates Manual Automatic
State No built-in state Has its own state
Use case Simple, static parts Dynamic, data-driven parts
Performance Lighter weight Slightly heavier

LiveComponents are useful for making interactive parts of your app that change often.

12. Tips for Better LiveView Apps

12.1 Improving Performance

Here are some ways to make your Phoenix LiveView app run faster:

Tip How to do it
Make database queries better - Use fewer queries
- Don't load too much data at once
- Use pagination
- Use caching
Use caching - Store often-used data
- Use tools like Cachex or ConCache
Make templates simpler - Avoid complex calculations in templates
- Use template caching
- Use partials
Use LiveView's built-in tools - Use diffing and patching features

12.2 Finding and Fixing Errors

Here's how to spot and fix problems in your Phoenix LiveView app:

Method What to do
Use browser developer tools - Check the console for errors
- Look at network requests and responses
Use Phoenix debugging tools - Try the debugger
- Use the logger
Test your app well - Write tests with ExUnit and Wallaby
Use error tracking tools - Try Sentry or Rollbar
- Watch your app's performance
- Fix errors quickly

These tips will help you make your LiveView app run better and fix problems faster.

13. Wrapping Up

13.1 Key Points to Remember

Here are the main things to keep in mind as you finish this guide to Phoenix LiveView:

Point Description
LiveView's purpose Makes real-time, interactive web apps
Core concepts mount, handle_event, and render functions
Built-in features Use diffing and patching for better performance
Best practices Use caching, pagination, and simple templates
Testing and fixing Try ExUnit, Wallaby, and the debugger

13.2 Where to Learn More

To keep improving your Phoenix LiveView skills, check out these resources:

Resource What it offers
Official docs Full guide with tutorials and examples
Online groups Connect with other developers, ask questions
Blogs and guides Learn new tips and methods
Books and classes Deep dive into LiveView and web development
Open-source projects Get hands-on experience

These tools will help you build better LiveView apps and solve problems faster.

FAQs

What is the difference between Phoenix and Phoenix LiveView?

Phoenix LiveView

Phoenix and Phoenix LiveView are two tools for building web apps. They work differently:

Feature Phoenix Phoenix LiveView
Request handling Each HTTP request uses a new process One process handles a WebSocket connection
Page updates Full page reload needed Real-time updates without reload
Best for Traditional web apps Interactive, real-time apps

Here's how they work in practice:

Phoenix:

  1. User submits a form
  2. Server processes the request
  3. Server updates the database
  4. Server sends a new HTML page to the client
  5. Client's browser loads the new page

LiveView:

  1. User submits a form
  2. Server processes the request
  3. Server updates the database
  4. Server sends only the changed data to the client
  5. Client's page updates without reloading

LiveView is good for making web apps that need to show changes right away, like:

  • Live dashboards
  • Team editing tools
  • Online games

These apps work better with LiveView because it can update parts of the page quickly without loading a whole new page.

Related posts

Why not level up your reading with

Stay up-to-date with the latest developer news every time you open a new tab.

Read more