Initial Setup
Want to add real-time features to your Phoenix app? This initial setup guide adds Phoenix LiveView to an existing Phoenix application in minutes. By the end, you’ll have LiveView configured and will create your first interactive page.
This tutorial provides 0-5% coverage—just enough to get LiveView working in your Phoenix app. For deeper learning, continue to Quick Start (5-30% coverage).
Prerequisites
Before adding LiveView, you need:
- Phoenix framework installed and working (Phoenix 1.7+)
- Elixir 1.14+ and Erlang/OTP 25+ installed
- Existing Phoenix application (or create new one)
- Basic Phoenix knowledge (routing, controllers, views) - see Phoenix by Example
- Basic Elixir knowledge - see Elixir by Example
Important: Phoenix LiveView requires Phoenix 1.5+. Phoenix 1.7+ includes LiveView by default in new projects.
Learning Objectives
By the end of this tutorial, you will be able to:
- Add LiveView dependencies to existing Phoenix app
- Configure LiveView in application setup
- Update router for LiveView routes
- Create your first LiveView module
- Render LiveView in browser
- Handle basic user interactions
Check Phoenix Version
Verify you have Phoenix 1.7+ (includes LiveView by default):
mix phx.new --versionExpected output:
Phoenix installer v1.7.10If you see a lower version, update Phoenix:
mix archive.uninstall phx_new
mix archive.install hex phx_newOption 1: New Phoenix Project (Recommended)
Create a new Phoenix project with LiveView included:
# Create new Phoenix app with LiveView
mix phx.new my_app --live
# Navigate to project
cd my_app
# Install dependencies
mix deps.get
# Create database
mix ecto.create
# Start server
mix phx.serverVisit http://localhost:4000 - LiveView is ready!
What gets configured:
- LiveView dependencies in
mix.exs - LiveView socket configuration in
endpoint.ex - LiveView signing salt in
config.exs - Example LiveView templates
- Asset build configuration for LiveView JavaScript
Option 2: Add to Existing Phoenix App
If you have an existing Phoenix 1.5+ app without LiveView:
Step 1: Add Dependencies
Edit mix.exs and add LiveView dependencies:
defp deps do
[
# ... existing dependencies
{:phoenix_live_view, "~> 0.20.0"},
{:floki, ">= 0.30.0", only: :test}
]
endInstall dependencies:
mix deps.getStep 2: Configure LiveView Socket
Edit lib/my_app_web/endpoint.ex and add LiveView socket configuration:
defmodule MyAppWeb.Endpoint do
use Phoenix.Endpoint, otp_app: :my_app
# Add LiveView socket
socket "/live", Phoenix.LiveView.Socket,
websocket: [connect_info: [session: @session_options]]
# ... rest of endpoint configuration
endStep 3: Add Signing Salt
Edit config/config.exs and add LiveView signing salt:
config :my_app, MyAppWeb.Endpoint,
live_view: [signing_salt: "YOUR_SECRET_SIGNING_SALT"]Generate a signing salt:
mix phx.gen.secret 32Use the generated string as signing_salt.
Step 4: Update Router Configuration
Edit lib/my_app_web/router.ex and import LiveView helpers:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
import Phoenix.LiveView.Router # Add this line
# ... rest of router configuration
endStep 5: Add LiveView JavaScript
Edit assets/js/app.js and add LiveView hooks:
// Import Phoenix LiveView
import { Socket } from "phoenix";
import { LiveSocket } from "phoenix_live_view";
// Set up LiveView socket
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content");
let liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken } });
// Connect LiveView
liveSocket.connect();
// Expose for debugging (optional)
window.liveSocket = liveSocket;Install LiveView npm package:
cd assets
npm install phoenix_live_view --save
cd ..Step 6: Add CSRF Meta Tag
Edit your layout template (e.g., lib/my_app_web/templates/layout/root.html.heex) and add CSRF token meta tag in <head>:
<meta name="csrf-token" content={get_csrf_token()} />Step 7: Recompile
mix compileCreating Your First LiveView
Create a simple counter LiveView to verify setup.
Step 1: Create LiveView Module
Create lib/my_app_web/live/counter_live.ex:
defmodule MyAppWeb.CounterLive do
use MyAppWeb, :live_view
@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, count: 0)}
end
@impl true
def render(assigns) do
~H"""
<div class="counter">
<h1>Counter: <%= @count %></h1>
<button phx-click="increment">Increment</button>
<button phx-click="decrement">Decrement</button>
</div>
"""
end
@impl true
def handle_event("increment", _params, socket) do
{:noreply, update(socket, :count, &(&1 + 1))}
end
@impl true
def handle_event("decrement", _params, socket) do
{:noreply, update(socket, :count, &(&1 - 1))}
end
endWhat this does:
mount/3: Initialize state (count = 0)render/1: Render HTML template with HEExhandle_event/3: Handle button clicks (increment/decrement)
Step 2: Add LiveView Route
Edit lib/my_app_web/router.ex and add LiveView route:
scope "/", MyAppWeb do
pipe_through :browser
# Add LiveView route
live "/counter", CounterLive
# ... existing routes
endStep 3: Start Server
mix phx.serverVisit http://localhost:4000/counter
What you should see:
- Counter displaying “Counter: 0”
- Two buttons (Increment, Decrement)
- Clicking buttons updates count in real-time (no page reload!)
Verifying LiveView Works
Test the counter:
- Click “Increment” - count goes to 1
- Click “Increment” again - count goes to 2
- Click “Decrement” - count goes to 1
- Open browser DevTools → Network tab
- Click button - you’ll see WebSocket frames, not HTTP requests
This confirms: LiveView is connected via WebSocket and updating DOM in real-time!
Project Structure
After adding LiveView, your structure includes:
my_app/
├── lib/
│ └── my_app_web/
│ ├── live/ # LiveView modules
│ │ └── counter_live.ex
│ ├── router.ex # Routes (live "/path", Module)
│ ├── endpoint.ex # WebSocket configuration
│ └── ...
├── assets/
│ └── js/
│ └── app.js # LiveView JavaScript setup
├── config/
│ └── config.exs # LiveView signing salt
└── mix.exs # LiveView dependenciesLiveView file organization:
- Simple LiveViews: Single file with
mount/3,render/1,handle_event/3 - Complex LiveViews: Separate template file (
.html.heex) - LiveComponents: Reusable components in
lib/my_app_web/live/components/
Common Issues
“Cannot connect to WebSocket”
Cause: LiveView socket not configured in endpoint.ex
Fix: Add socket configuration:
socket "/live", Phoenix.LiveView.Socket,
websocket: [connect_info: [session: @session_options]]“Invalid signing salt”
Cause: Missing or incorrect signing salt in config.exs
Fix: Generate and add signing salt:
# Generate salt
mix phx.gen.secret 32
# Add to config/config.exs
config :my_app, MyAppWeb.Endpoint,
live_view: [signing_salt: "GENERATED_SALT_HERE"]“CSRF token not found”
Cause: Missing CSRF meta tag in layout
Fix: Add to root.html.heex:
<meta name="csrf-token" content={get_csrf_token()} />LiveView doesn’t update on button click
Cause: LiveView JavaScript not loaded
Fix: Verify app.js includes LiveView setup:
import {LiveSocket} from "phoenix_live_view"
let liveSocket = new LiveSocket("/live", Socket, ...)
liveSocket.connect()Compilation error: “undefined function ~H”
Cause: Using Phoenix < 1.7 (HEEx not available)
Fix: Upgrade Phoenix or use older LiveView syntax:
# Phoenix 1.7+ (HEEx)
~H"""
<div><%= @count %></div>
"""
# Phoenix < 1.7 (EEx)
~L"""
<div><%= @count %></div>
"""LiveView Lifecycle
Understanding the LiveView lifecycle helps debug issues:
- HTTP Request: User navigates to
/counter(regular HTTP) - Static Render: Server renders initial HTML (count = 0)
- WebSocket Connect: Browser establishes WebSocket connection
- mount/3: Server initializes LiveView state
- Stateful Render: LiveView ready for interactions
- User Event: User clicks button (phx-click event)
- handle_event/3: Server processes event, updates state
- Patch DOM: Server sends HTML diff, browser patches DOM
Key insight: First render is static HTML (fast initial load), then WebSocket for interactivity.
Next Steps
Now that LiveView is working:
- Quick Start - Build a complete LiveView feature with forms and validation
- By Example - Learn through 85 annotated code examples
- Experiment - Add more buttons, display different data, try different events
Recommended workflow: Quick Start → practice with your own ideas → use By Example as reference.
Summary
You now have:
- ✅ LiveView dependencies installed
- ✅ WebSocket socket configured
- ✅ Signing salt generated and configured
- ✅ LiveView JavaScript connected
- ✅ First working LiveView (counter)
- ✅ LiveView route in router
Total setup time: ~10-15 minutes (new project) or ~30 minutes (existing project)
Next: Try the Quick Start tutorial to build a real-world LiveView feature with forms, validation, and PubSub.