Main public API for stashing and recovering Phoenix.LiveView assigns.
LiveStash helps preserve selected server-side assigns across reconnects.
You explicitly choose which assigns to persist and when to persist them.
This module:
- integrates with
on_mountviause LiveStash - initializes the selected adapter
- delegates persistence and recovery operations to that adapter
Quick start
Add use LiveStash to your LiveView:
defmodule MyAppWeb.CounterLive do
use MyAppWeb, :live_view
use LiveStash
endStash assigns after state-changing events:
def handle_event("increment", _, socket) do
socket
|> assign(:count, socket.assigns.count + 1)
|> LiveStash.stash_assigns([:count])
|> then(&{:noreply, &1})
endRecover stashed state in mount/3:
def mount(_params, _session, socket) do
socket
|> LiveStash.recover_state()
|> case do
{:recovered, recovered_socket} ->
# socket with previously stashed assigns is recovered
recovered_socket
{_, socket} ->
# could not recover assigns, proceed with standard setup using returned socket
# ...
end
|> then(&{:ok, &1})
endRecovery statuses
recover_state/1 returns {status, socket} where status is one of:
:new- fresh LiveView process, with no previously stashed state:recovered- state was found and applied:not_found- state was not found for this LiveView:error- adapter failed to recover state
Adapter selection
The default adapter is LiveStash.Adapters.BrowserMemory.
You can override it per LiveView:
use LiveStash, adapter: LiveStash.Adapters.ETSAdapters used by your app must also be enabled in config:
config :live_stash,
adapters: [LiveStash.Adapters.BrowserMemory, LiveStash.Adapters.ETS]
Summary
Functions
Injects LiveStash support into a Phoenix.LiveView. This macro expands to
Initializes stash support for a socket using the configured adapter.
LiveView on_mount callback used by use LiveStash.
Recovers previously stashed state and returns {status, socket}.
Clears stashed state for the current LiveView socket.
Stashes the specified assigns from socket.assigns.
Types
Functions
Injects LiveStash support into a Phoenix.LiveView. This macro expands to:
on_mount({LiveStash, opts})so that LiveStash can initialize stash handling during the LiveView mount/3
lifecycle.
Options
The opts are forwarded to LiveStash.on_mount/4 and ultimately to the
configured adapter. Most adapters use :adapter to select the persistence
backend:
use LiveStash, adapter: LiveStash.Adapters.ETSNote: adapters must also be enabled in config :live_stash, :adapters.
Example
defmodule MyAppWeb.CounterLive do
use MyAppWeb, :live_view
use LiveStash, adapter: LiveStash.Adapters.BrowserMemory
end
@spec init_stash( socket :: Phoenix.LiveView.Socket.t(), session :: Keyword.t(), opts :: Keyword.t() ) :: Phoenix.LiveView.Socket.t()
Initializes stash support for a socket using the configured adapter.
This function is called from on_mount/4. In normal usage, prefer
use LiveStash and do not call this function directly.
It validates that the selected adapter is active in
config :live_stash, :adapters.
LiveView on_mount callback used by use LiveStash.
It initializes stash handling for the current socket and continues the mount lifecycle.
@spec recover_state(socket :: Phoenix.LiveView.Socket.t()) :: {recovery_status(), Phoenix.LiveView.Socket.t()}
Recovers previously stashed state and returns {status, socket}.
This function is typically called in mount/3. Recovery does not clear the
stored state; use reset_stash/1 when you want to remove it explicitly.
Examples
def mount(_params, _session, socket) do
socket
|> LiveStash.recover_state()
|> case do
{:recovered, recovered_socket} ->
recovered_socket
{_, socket} ->
start_new_game(socket)
end
|> then(&{:ok, &1})
end
@spec reset_stash(socket :: Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
Clears stashed state for the current LiveView socket.
Examples
def handle_event("restart_game", _params, socket) do
socket
|> LiveStash.reset_stash()
|> start_new_game()
|> then(&{:noreply, &1})
end
@spec stash_assigns(socket :: Phoenix.LiveView.Socket.t(), keys :: [atom()]) :: Phoenix.LiveView.Socket.t()
Stashes the specified assigns from socket.assigns.
Every key must be an atom and should exist in socket.assigns.
Call this after assign updates to keep persisted state in sync.
Examples
def handle_event("increment", _, socket) do
socket
|> assign(:count, socket.assigns.count + 1)
|> LiveStash.stash_assigns([:count])
|> then(&{:noreply, &1}) end