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, stored_keys: [:count]
endStash assigns after state-changing events:
def handle_event("increment", _, socket) do
socket
|> assign(:count, socket.assigns.count + 1)
|> LiveStash.stash()
|> 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 assigns from socket.assigns declared at the module level.
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(socket :: Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
Stashes assigns from socket.assigns declared at the module level.
Examples
use LiveStash, stored_keys: [:count, :username] # assigns are declared at the module level
def handle_event("increment", _, socket) do
socket
|> assign(:count, socket.assigns.count + 1)
|> LiveStash.stash()
|> then(&{:noreply, &1})
end