Skip to main content

Overview

A LiveView is a process that receives events, updates its state, and renders updates to a page as diffs. LiveView begins as a regular HTTP request and HTML response, and then upgrades to a stateful view on client connect, guaranteeing a regular HTML page even if JavaScript is disabled. Socket assigns are stateful values kept on the server side.

Life-cycle

The LiveView life-cycle follows this sequence:
  1. mount/3 - Invoked on both initial HTTP render and WebSocket connection
  2. handle_params/3 - Invoked after mount and on live patch events
  3. render/1 - Renders the template whenever state changes

Callbacks

mount/3

@callback mount(
  params :: unsigned_params() | :not_mounted_at_router,
  session :: map,
  socket :: Socket.t()
) :: {:ok, Socket.t()} | {:ok, Socket.t(), keyword()}
The LiveView entry-point called twice: once for initial page load and again to establish the live socket.
params
map | :not_mounted_at_router
A map of string keys containing query params and router path parameters. Returns :not_mounted_at_router if not mounted at router.
session
map
The connection session containing private data set by the application.
socket
Socket.t()
The LiveView socket.
return
{:ok, socket} | {:ok, socket, options}
Returns updated socket with optional configuration:
  • :temporary_assigns - Assigns reset after each render
  • :layout - Optional layout override
Example:
def mount(_params, _session, socket) do
  if connected?(socket), do: :timer.send_interval(1000, self(), :tick)
  {:ok, assign(socket, date: :calendar.local_time())}
end

render/1

@callback render(assigns :: Socket.assigns()) :: Phoenix.LiveView.Rendered.t()
Renders a template. Invoked whenever LiveView detects new content must be rendered and sent to the client.
assigns
map
The socket assigns map.
return
Phoenix.LiveView.Rendered.t()
Must return a template defined via the ~H sigil.
Example:
def render(assigns) do
  ~H"""
  <div>Hello {@name}!</div>
  """
end

handle_params/3

@callback handle_params(
  unsigned_params(),
  uri :: String.t(),
  socket :: Socket.t()
) :: {:noreply, Socket.t()}
Invoked after mount and whenever there is a live patch event.
params
map
Current parameters including router params and query params.
uri
string
The current URI from the client.
socket
Socket.t()
The LiveView socket.

handle_event/3

@callback handle_event(
  event :: binary,
  unsigned_params(),
  socket :: Socket.t()
) :: {:noreply, Socket.t()} | {:reply, map, Socket.t()}
Invoked to handle events sent by the client.
event
string
The event name (e.g., “save”, “delete”).
params
map
The event payload as a map.
socket
Socket.t()
The LiveView socket.
return
{:noreply, socket} | {:reply, map, socket}
Returns updated socket, optionally with a reply map sent back to client.

handle_info/2

@callback handle_info(msg :: term, socket :: Socket.t()) :: {:noreply, Socket.t()}
Invoked to handle messages from other Elixir processes.
msg
term
The message received from another process.
socket
Socket.t()
The LiveView socket.

handle_async/3

@callback handle_async(
  name :: term,
  async_fun_result :: {:ok, term} | {:exit, term},
  socket :: Socket.t()
) :: {:noreply, Socket.t()}
Invoked when the result of a start_async/3 operation is available.
name
term
The name given to start_async/3.
result
{:ok, result} | {:exit, reason}
The async function result wrapped in :ok or :exit.
socket
Socket.t()
The LiveView socket.

handle_call/3

@callback handle_call(msg :: term, {pid, reference}, socket :: Socket.t()) ::
  {:noreply, Socket.t()} | {:reply, term, Socket.t()}
Invoked to handle synchronous call messages from other Elixir processes via GenServer.call/2.
msg
term
The message sent via GenServer.call/2.
from
{pid, reference}
The caller’s PID and reply reference.
socket
Socket.t()
The LiveView socket.
return
{:noreply, socket} | {:reply, term, socket}
Either :noreply for no response or :reply with a return value for the caller.
Example:
def handle_call(:get_state, _from, socket) do
  {:reply, socket.assigns, socket}
end

handle_cast/2

@callback handle_cast(msg :: term, socket :: Socket.t()) ::
  {:noreply, Socket.t()}
Invoked to handle asynchronous cast messages from other Elixir processes via GenServer.cast/2.
msg
term
The message sent via GenServer.cast/2.
socket
Socket.t()
The LiveView socket.
return
{:noreply, socket}
Returns updated socket.
Example:
def handle_cast({:update_data, data}, socket) do
  {:noreply, assign(socket, :data, data)}
end

terminate/2

@callback terminate(reason, socket :: Socket.t()) :: term
  when reason: :normal | :shutdown | {:shutdown, :left | :closed | term}
Invoked when the LiveView is terminating. Use this to clean up resources.
reason
:normal | :shutdown | {:shutdown, reason}
The termination reason:
  • :normal - Normal termination
  • :shutdown - Application shutdown
  • {:shutdown, :left} - User navigated away
  • {:shutdown, :closed} - Connection closed
socket
Socket.t()
The LiveView socket.
return
term
Return value is ignored.
Example:
def terminate(_reason, socket) do
  # Clean up resources
  :ok
end

Functions

assign/3

Adds a key-value pair to socket assigns.
assign(socket, :name, "Elixir")
socket
Socket.t()
The LiveView socket.
key
atom
The assign key.
value
any
The assign value.
return
Socket.t()
Updated socket with new assign.

assign_new/3

Assigns a key with value from function if one does not yet exist.
assign_new(socket, :current_user, fn -> Accounts.get_user!(user_id) end)
socket
Socket.t()
The LiveView socket.
key
atom
The assign key.
fun
function
Function returning the value (0 or 1 arity).

update/3

Updates an existing key with a function.
update(socket, :count, &(&1 + 1))
socket
Socket.t()
The LiveView socket.
key
atom
The assign key to update.
fun
function
Function receiving current value and returning updated value.

push_event/3

Pushes an event to the client.
push_event(socket, "scores", %{points: 100, user: "josé"})
socket
Socket.t()
The LiveView socket.
event
string
The event name.
payload
map
The event data.
opts
keyword
default:"[]"
Options:
  • :dispatch - :before or :after patch (default: :after)

push_navigate/2

Annotates the socket for navigation to another LiveView in the same live_session.
push_navigate(socket, to: "/")
push_navigate(socket, to: "/", replace: true)
socket
Socket.t()
The LiveView socket.
opts
keyword
Options:
  • :to (required) - The path to navigate to
  • :replace - Replace browser history (default: false)

push_patch/2

Annotates the socket for navigation within the current LiveView.
push_patch(socket, to: "/")
push_patch(socket, to: "/", replace: true)
socket
Socket.t()
The LiveView socket.
opts
keyword
Options:
  • :to (required) - The path to patch to
  • :replace - Replace browser history (default: false)

redirect/2

Annotates the socket for redirect to a destination path.
redirect(socket, to: "/")
redirect(socket, external: "https://example.com")
socket
Socket.t()
The LiveView socket.
opts
keyword
Options:
  • :to - Local path to redirect to
  • :external - External URL to redirect to
  • :status - HTTP status code (default: 302)

put_flash/3

Adds a flash message to the socket.
put_flash(socket, :info, "It worked!")
put_flash(socket, :error, "You can't access that page")
socket
Socket.t()
The LiveView socket.
kind
atom
The flash type (:info, :error, etc.).
msg
string
The flash message.

stream/4

Assigns a new stream or inserts items into an existing stream.
stream(socket, :songs, songs)
stream(socket, :songs, songs, at: 0, limit: 10)
socket
Socket.t()
The LiveView socket.
name
atom | string
The stream name.
items
Enumerable.t()
Items to insert.
opts
keyword
default:"[]"
Options:
  • :at - Index to insert items (default: -1)
  • :reset - Reset stream on client (default: false)
  • :limit - Limit items in UI

stream_insert/4

Inserts a new item or updates an existing item in the stream.
stream_insert(socket, :songs, song)
stream_insert(socket, :songs, song, at: 0, limit: -10)
socket
Socket.t()
The LiveView socket.
name
atom | string
The stream name.
item
any
Item to insert or update.
opts
keyword
default:"[]"
Options:
  • :at - Index to insert item (default: -1)
  • :limit - Limit items in UI

stream_delete/3

Deletes an item from the stream.
stream_delete(socket, :songs, song)
socket
Socket.t()
The LiveView socket.
name
atom | string
The stream name.
item
any
Item to delete.

stream_delete_by_dom_id/3

Deletes a stream item by its DOM ID.
stream_delete_by_dom_id(socket, :songs, "songs-123")
socket
Socket.t()
The LiveView socket.
name
atom | string
The stream name.
id
string
The DOM ID of the item to delete.

stream_configure/3

Configures a stream with options.
stream_configure(socket, :songs, dom_id: &("song-#{&1.id}"))
socket
Socket.t()
The LiveView socket.
name
atom | string
The stream name.
opts
keyword
Options:
  • :dom_id - Function to generate DOM IDs

assign_async/3

Assigns keys asynchronously using a task.
assign_async(socket, :org, fn -> {:ok, %{org: fetch_org!(slug)}} end)
socket
Socket.t()
The LiveView socket.
keys
atom | list
Key or list of keys to assign.
func
function
Function returning {:ok, assigns} or {:error, reason}.
opts
keyword
default:"[]"
Options:
  • :supervisor - Task.Supervisor to use
  • :reset - Remove previous results (default: false)

start_async/3

Wraps a function in an asynchronous task.
start_async(socket, :my_task, fn -> fetch_data() end)
socket
Socket.t()
The LiveView socket.
name
term
Name for the async operation.
func
function
Function to execute asynchronously.
opts
keyword
default:"[]"
Options:
  • :supervisor - Task.Supervisor to use

send_update/3

Asynchronously updates a LiveComponent with new assigns.
send_update(Cart, id: "cart", status: "cancelled")
send_update(pid, Cart, id: "cart", status: "cancelled")
pid
pid
default:"self()"
The LiveView process ID.
module
atom
The LiveComponent module.
assigns
keyword | map
Assigns to update (must include :id).

cancel_async/3

Cancels one or more async operations.
cancel_async(socket, :org)
cancel_async(socket, [:org, :profile])
cancel_async(socket, async_result, :cancel)
socket
Socket.t()
The LiveView socket.
keys
atom | list | AsyncResult.t()
Async key(s) to cancel or an AsyncResult struct.
reason
term
default:"{:shutdown, :cancel}"
The cancellation reason.

attach_hook/4

Attaches a function by name for a lifecycle stage.
attach_hook(socket, :my_hook, :handle_event, fn event, params, socket ->
  # Handle event
  {:cont, socket}
end)
socket
Socket.t()
The LiveView socket.
name
atom
Hook name.
stage
atom
Lifecycle stage: :handle_params, :handle_event, :handle_info, :handle_async, :after_render.
fun
function
Hook function.

connected?/1

Returns true if the socket is connected.
if connected?(socket), do: subscribe_to_updates()
socket
Socket.t()
The LiveView socket.
return
boolean
true if connected via WebSocket, false during initial HTTP render.

get_connect_params/1

Accesses the connect params sent by the client.
get_connect_params(socket)["time_zone"]
socket
Socket.t()
The LiveView socket.
return
map | nil
Connect params on connected mount, nil when disconnected.

get_connect_info/2

Gets connection metadata by key.
get_connect_info(socket, :peer_data)
get_connect_info(socket, :x_headers)
socket
Socket.t()
The LiveView socket.
key
atom
Connection info key (:peer_data, :x_headers, :uri, :user_agent, etc.).
return
term | nil
Connection metadata value or nil.

static_changed?/1

Checks if static assets have changed since the LiveView was rendered.
if static_changed?(socket) do
  push_navigate(socket, to: "/")
end
socket
Socket.t()
The LiveView socket.
return
boolean
true if static assets changed during the connection.

clear_flash/1

Clears all flash messages.
clear_flash(socket)
socket
Socket.t()
The LiveView socket.

clear_flash/2

Clears a specific flash message key.
clear_flash(socket, :info)
socket
Socket.t()
The LiveView socket.
key
atom
Flash key to clear.

detach_hook/3

Detaches a hook by ID and lifecycle stage.
detach_hook(socket, :my_hook, :handle_event)
socket
Socket.t()
The LiveView socket.
id
atom
Hook identifier.
stage
atom
Lifecycle stage (:mount, :handle_params, :handle_event, :handle_info, :after_render).

allow_upload/3

Allows an upload for the provided name.
allow_upload(socket, :avatar, accept: ~w(.jpg .jpeg), max_entries: 2)
allow_upload(socket, :avatar, accept: :any)
socket
Socket.t()
The LiveView socket.
name
atom
Upload name.
opts
keyword
Options:
  • :accept (required) - File extensions list or :any
  • :max_entries - Maximum files (default: 1)
  • :max_file_size - Maximum bytes (default: 8MB)
  • :chunk_size - Chunk size in bytes (default: 64KB)
  • :auto_upload - Auto-upload on selection (default: false)
  • :external - Function for external uploads
  • :progress - Progress callback function

Build docs developers (and LLMs) love