- Remove
@inner_content
in components and introducerender_block
for rendering component@inner_block
- Fix
redirect(socket, external: ...)
when returned from an event - Properly follow location hashes on live patch/redirect
- Fix failure in
Phoenix.LiveViewTest
when phx-update has non-HTML nodes as children - Fix
phx_trigger_action
submitting the form before the DOM updates are complete
- Fix race condition on
phx-trigger-action
causing reconnects before server form submit
- Optimize DOM prepend and append operations
- Add
Phoenix.LiveView.send_update_after/3
- Fix scroll position when using back/forward with
live_redirect
's - Handle recursive components when generating diffs
- Support hard redirects on mount
- Properly track nested components on deletion on
Phoenix.LiveViewTest
- Fix hidden inputs throwing selection range error
- Support
render_layout
with LiveEEx
- Fix focused inputs being overwritten by latent patch
- Fix LiveView error when
"_target"
input name contains array - Fix change tracking when passing a do-block to components
- Fix Map of assigns together with
@inner_content
causingno function clause matching in Keyword.put/3
error - Fix
LiveViewTest
failing to patch children properly for append/prepend based phx-update's - Fix argument error when providing
:as
option to alive
route - Fix page becoming unresponsive when the server crashes while handling a live patch
- Fix empty diff causing pending data-ref based updates, such as classes and disable-with content to not be updated
- Fix bug where throttling keydown events would eat key presses
- Fix textarea's failing to be disabled on form submit
- Fix text node DOM memory leak when using phx-update append/prepend
- Allow
:router
to be given torender_component
- Display file on compile warning for
~L
- Log error on client when using a hook without a DOM ID
- Optimize phx-update append/prepend based DOM updates
- Fix nested
live_render
's failing to be torn down when removed from the DOM in certain cases - Fix LEEx issue for nested conditions failing to be re-evaluated
- Fix IE11 issue where
document.activeElement
creates a null reference - Fix setup and teardown of root views when explicitly calling
liveSocket.disconnect()
followed byliveSocket.connect()
- Fix
error_tag
failing to be displayed for non-text based inputs such as selects and checkboxes as the phx-no-feedback class was always applied - Fix
phx-error
class being applied onlive_redirect
- Properly handle Elixir's special variables, such as
__MODULE__
- No longer set disconnected class during patch
- Track flash keys to fix back-to-back flashes from being discarded
- Properly handle empty component diffs in the client for cases where the component has already been removed on the server
- Make sure components in nested live views do not conflict
- Fix
phx-static
not being sent from the client for child views - Do not fail when trying to delete a view that was already deleted
- Ensure
beforeDestroy
is called on hooks in children of a removed element
- Allow the whole component static subtree to be shared when the component already exists on the client
- Add telemetry events to
mount
,handle_params
, andhandle_event
- Add
push_event
for pushing events and data from the server to the client - Add client
handleEvent
hook method for receiving events pushed from the server - Add ability to receive a reply to a
pushEvent
from the server via{:reply, map, socket}
- Use event listener for popstate to avoid conflicting with user-defined popstate handlers
- Log error on client when rendering a component with no direct DOM children
- Make
assigns.myself
a struct to catch mistakes - Log if component doesn't exist on
send_update
, raise if module is unavailable
- Fix duplicate debounced events from being triggered on blur with timed debounce
- Fix client error when live_redirected'd route results in a redirect to a non-live route on the server
- Fix DOM siblings being removed when a rootless component is updated
- Fix debounced input failing to send last change when blurred via Tab, Meta, or other non-printable keys
- Add
dom
option toLiveSocket
withonBeforeElUpdated
callback for external client library support of broad DOM operations
- Fix a bug where swapping a root template with components would cause the LiveView to crash
- Fix forced page refresh when push_redirect from a live_redirect
- Optimize component diffs to avoid sending empty diffs
- Optimize components to share static values
- [LiveViewTest] Automatically synchronize before render events
- No longer send event metadata by default. Metadata is now opt-in and user defined at the
LiveSocket
level. To maintain backwards compatiblity with pre-0.13 behaviour, you can provide the following metadata option:
let liveSocket = new LiveSocket("/live", Socket, {
params: {_csrf_token: csrfToken},
metadata: {
click: (e, el) => {
return {
altKey: e.altKey,
shiftKey: e.shiftKey,
ctrlKey: e.ctrlKey,
metaKey: e.metaKey,
x: e.x || e.clientX,
y: e.y || e.clientY,
pageX: e.pageX,
pageY: e.pageY,
screenX: e.screenX,
screenY: e.screenY,
offsetX: e.offsetX,
offsetY: e.offsetY,
detail: e.detail || 1,
}
},
keydown: (e, el) => {
return {
altGraphKey: e.altGraphKey,
altKey: e.altKey,
code: e.code,
ctrlKey: e.ctrlKey,
key: e.key,
keyIdentifier: e.keyIdentifier,
keyLocation: e.keyLocation,
location: e.location,
metaKey: e.metaKey,
repeat: e.repeat,
shiftKey: e.shiftKey
}
}
}
})
- Fix error caused by Chrome sending a keydown event on native UI autocomplete without a
key
- Fix server error when a live navigation request issues a redirect
- Fix double window bindings when explicit calls to LiveSocket connect/disconnect/connect
- Add
Phoenix.LiveView.get_connect_info/1
- Add
Phoenix.LiveViewTest.put_connect_info/2
andPhoenix.LiveViewTest.put_connect_params/2
- Add support for tracking static asset changes on the page across cold server deploys
- Add support for passing a
@myself
target to a hook'spushEventTo
target - Add configurable metadata for events with new
metadata
LiveSocket option - Add
"_mounts"
key in connect params which specifies the number of times a LiveView has mounted
- Fix component
innerHTML
being discarded when a sibling DOM element appears above it, in cases where the component lacks a DOM ID - Fix Firefox reconnecting briefly during hard redirects
- Fix
phx-disable-with
and other pending attributes failing to be restored when an empty patch is returned by server - Ensure LiveView module is loaded before mount to prevent first application request logging errors if the very first request is to a connected LiveView
This version of LiveView comes with an overhaul of the testing module, more closely integrating your LiveView template with your LiveView events. For example, in previous versions, you could write this test:
render_click(live_view, "increment_by", %{by: 1})
However, there is no guarantee that there is any element on the page with a phx-click="increment"
attribute and phx-value-by
set to 1. With LiveView 0.12.0, you can now write:
live_view
|> element("#term .buttons a", "Increment")
|> render_click()
The new implementation will check there is a button at #term .buttons a
, with "Increment" as text, validate that it has a phx-click
attribute and automatically submit to it with all relevant phx-value
entries. This brings us closer to integration/acceptance test frameworks without any of the overhead and complexities of running a headless browser.
- Add
assert_patch/3
andassert_patched/2
for asserting on patches - Add
follow_redirect/3
to automatically follow redirects fromrender_*
events - Add
phx-trigger-action
form annotation to trigger an HTTP form submit on next DOM patch
- Fix
phx-target
@myself
targetting a sibling LiveView component with the same component ID - Fix
phx:page-loading-stop
firing before the DOM patch has been performed - Fix
phx-update="prepend"
failing to properly patch the DOM when the same ID is updated back to back - Fix redirects on mount failing to copy flash
-
phx-error-for
has been removed in favor ofphx-feedback-for
.phx-feedback-for
will set aphx-no-feedback
class whenever feedback has to be hidden -
Phoenix.LiveViewTest.children/1
has been renamed toPhoenix.LiveViewTest.live_children/1
-
Phoenix.LiveViewTest.find_child/2
has been renamed toPhoenix.LiveViewTest.find_live_child/2
-
Phoenix.LiveViewTest.assert_redirect/3
no longer matches on the flash, instead it returns the flash -
Phoenix.LiveViewTest.assert_redirect/3
no longer matches on the patch redirects, useassert_patch/3
instead -
Phoenix.LiveViewTest.assert_remove/3
has been removed. If the LiveView crashes, it will cause the test to crash too -
Passing a path with DOM IDs to
render_*
test functions is deprecated. Furthermore, they now require aphx-target="<%= @id %>"
on the given DOM ID:<div id="component-id" phx-target="component-id"> ... </div>
html = render_submit([view, "#component-id"], event, value)
In any case, this API is deprecated and you should migrate to the new element based API.
- Fix readonly states failing to be undone after an empty diff
- Fix dynamically added child failing to be joined by the client
- Fix teardown bug causing stale client sessions to attempt a rejoin on reconnect
- Fix orphaned prepend/append content across joins
- Track
unless
in LiveEEx engine
render_event
/render_click
and friends now expect a DOM ID selector to be given when working with components. For example, instead ofrender_click([live, "user-13"])
, you should writerender_click([live, "#user-13"])
, mirroring thephx-target
API.- Accessing the socket assigns directly
@socket.assigns[...]
in a template will now raise the exceptionPhoenix.LiveView.Socket.AssignsNotInSocket
. The socket assigns are available directly inside the template as LiveEExassigns
, such as@foo
and@bar
. Any assign access should be done using the assigns in the template where proper change tracking takes place.
- Trigger debounced events immediately on input blur
- Support
defaults
option onLiveSocket
constructor to configure defaultphx-debounce
andphx-throttle
values, allowing<input ... phx-debounce>
- Add
detail
key to click event metadata for detecting double/triple clicks
-
Remove
socket.assigns
during render to avoid change tracking bugs. If you were previously relying on passing@socket
to functions then referencing socket assigns, pass the explicit assign instead to your functions from the template. -
Removed
assets/css/live_view.css
. If you want to show a progress bar then inapp.css
, replace- @import "../../../../deps/phoenix_live_view/assets/css/live_view.css"; + @import "../node_modules/nprogress/nprogress.css";
and add
nprogress
toassets/package.json
. Full details in the Progress animation guide
- Fix client issue with greater than two levels of LiveView nesting
- Fix bug causing entire LiveView to be re-rendering with only a component changed
- Fix issue where rejoins would not trigger
phx:page-loading-stop
- Support deep change tracking so
@foo.bar
only executes and diffs when bar changes - Add
@myself
assign, to allow components to target themselves instead of relying on a DOM ID, for example:phx-target="<%= @myself %>"
- Optimize various client rendering scenarios for faster DOM patching of components and append/prepended content
- Add
enableProfiling()
anddisableProfiling()
toLiveSocket
for client performance profiling to aid the development process - Allow LiveViews to be rendered inside LiveComponents
- Add support for clearing flash inside components
- Rename socket assign
@live_view_module
to@live_module
- Rename socket assign
@live_view_action
to@live_action
- LiveView no longer uses the default app layout and
put_live_layout
is no longer supported. Instead, useput_root_layout
. Note, however, that the layout given toput_root_layout
must use@inner_content
instead of<%= render(@view_module, @view_template, assigns) %>
and that the root layout will also be used by regular views. Check the Live Layouts section of the docs.
- Fix loading states causing nested LiveViews to be removed during live navigation
- Only trigger
phx-update="ignore"
hook if data attributes have changed - Fix LiveEEx fingerprint bug causing no diff to be sent in certain cases
- Support collocated templates where an
.html.leex
template of the same basename of the LiveView will be automatically used forrender/1
- Add
live_title_tag/2
helper for automatic prefix/suffix on@page_title
updates
- Do not set ignored inputs and buttons as readonly
- Only decode paths in URIs
- Only destroy main descendents when replacing main
- Fix sibling component patches when siblings at same root DOM tree
- Do not pick the layout from
:use
on child LiveViews - Respect when the layout is set to
false
in the router and on mount - Fix sibling component patch when component siblings lack a container
- Make flash optional (i.e. LiveView will still work if you don't
fetch_flash
before)
- Raise if
:flash
is given as an assign - Support user-defined metadata in router
- Allow the router to be accessed as
socket.router
- Allow
MFArgs
as the:session
option in thelive
router macro - Trigger page loading event when main LV errors
- Automatially clear the flash on live navigation examples - only the newly assigned flash is persisted
- Support
phx-disable-with
on live redirect and live patch links
- Fix focus issue on date and time inputs
- Fix LiveViews failing to mount when page restored from back/forward cache following a
redirect
on the server - Fix IE coercing
undefined
to string when issuing pushState - Fix IE error when focused element is null
- Fix client error when using components and live navigation where a dynamic template is rendered
- Fix latent component diff causing error when component removed from DOM before patch arrives
- Fix race condition where a component event received on the server for a component already removed by the server raised a match error
- Remove
Phoenix.LiveView.Flash
in favor of:fetch_live_flash
imported byPhoenix.LiveView.Router
- Live layout must now access the child contents with
@inner_content
instead of invoking the LiveView directly - Returning
:stop
tuples from LiveViewmount
orhandle_[params|call|cast|info|event]
is no longer supported. LiveViews are stopped when issuing aredirect
orpush_redirect
- Add
put_live_layout
plug to put the root layout used for live routes - Allow
redirect
andpush_redirect
from mount - Use acknowledgement tracking to avoid patching inputs until the server has processed the form event
- Add css loading states to all phx bound elements with event specfic css classes
- Dispatch
phx:page-loading-start
andphx:page-loading-stop
on window for live navigation, initial page loads, and form submits, for user controlled page loading integration - Allow any phx bound element to specify
phx-page-loading
to dispatch loading events above when the event is pushed - Add client side latency simulator with new
enableLatencySim(milliseconds)
anddisableLatencySim()
- Add
enableDebug()
anddisableDebug()
toLiveSocket
for ondemand browser debugging from the web console - Do not connect LiveSocket WebSocket or bind client events unless a LiveView is found on the page
- Add
transport_pid/1
to return the websocket transport pid when the socket is connected
- Fix issue where a failed mount from a
live_redirect
would reload the current URL instead of the attempted new URL
- Fix checkbox bug failing to send
phx-change
event to the server in certain cases - Fix checkbox bug failing to maintain checked state when a checkbox is programmatically updated by the server
- Fix select bug in Firefox causing the highlighted index to jump when a patch is applied during hover state
live_redirect
was removed in favor ofpush_patch
(for updating the URL and params of the current LiveView) andpush_redirect
(for updating the URL to another LiveView)live_link
was removed in favor oflive_patch
(for updating the URL and params of the current LiveView) andlive_redirect
(for updating the URL to another LiveView)Phoenix.LiveViewTest.assert_redirect
no longer accepts an anonymous function in favor of executing the code prior to asserting the redirects, just likeassert_receive
.
- Support
@live_view_action
in LiveViews to simplify tracking of URL state - Recovery form input data automatically on disconnects or crash recovery
- Add
phx-auto-recover
form binding for specialized recovery - Scroll to top of page while respecting anchor hash targets on
live_patch
andlive_redirect
- Add
phx-capture-click
to use event capturing to bind a click event as it propagates inwards from the target - Revamp flash support so it works between static views, live views, and components
- Add
phx-key
binding to scopephx-window-keydown
andphx-window-keyup
events
- Send
phx-value-*
on key events - Trigger
updated
hook callbacks onphx-update="ignore"
container when the container's attributes have changed - Fix nested
phx-update="append"
raising ArgumentError in LiveViewTest - Fix updates not being applied in rare cases where an leex template is wrapped in an if expression
- LiveView
mount/2
has been deprecated in favor ofmount/3
. The params are now passed as the first argument tomount/3
, followed by the session and socket.
- The socket session now accepts only string keys
- Allow window beforeunload to be cancelled without losing websocket connection
- Fix handle_params not decoding URL path parameters properly
- Fix LiveViewTest error when routing at root path
- Fix URI encoded params failing to be decoded in
handle_params
- Fix component target failing to locate correct component when the target is on an input tag
- Fix optimization bug causing some DOM nodes to be removed on updates
- Fix phx-change bug causing phx-target to not be used
LiveView now makes the connection session automatically available in LiveViews. However, to do so, you need to configure your endpoint accordingly, otherwise LiveView will fail to connect.
The steps are:
-
Find
plug Plug.Session, ...
in your endpoint.ex and move the options...
to a module attribute:@session_options [ ... ]
-
Change the
plug Plug.Session
to use said attribute:plug Plug.Session, @session_options
-
Also pass the
@session_options
to your LiveView socket:socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]
-
You should define the CSRF meta tag inside in your layout, before
app.js
is included:<%= csrf_meta_tag() %> <script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
-
Then in your app.js:
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content"); let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}});
Also note that the session from now on will have string keys. LiveView will warn if atom keys are used.
- Respect new tab behavior in
live_link
- Add
beforeUpdate
andbeforeDestroy
JS hooks - Make all assigns defined on the socket mount available on the layout on first render
- Provide support for live layouts with new
:layout
option - Detect duplicate IDs on the front-end when DEBUG mode is enabled
- Automatically forward the session to LiveView
- Support "live_socket_id" session key for identifying (and disconnecting) LiveView sockets
- Add support for
hibernate_after
on LiveView processes - Support redirecting to full URLs on
live_redirect
andredirect
- Add
offsetX
andoffsetY
to click event metadata - Allow
live_link
andlive_redirect
to exist anywhere in the page and it will always target the main LiveView (the one defined at the router)
phx-target="window"
has been removed in favor ofphx-window-keydown
,phx-window-focus
, etc, and thephx-target
binding has been repurposed for targetting LiveView and LiveComponent events from the clientPhoenix.LiveView
no longer definedlive_render
andlive_link
. These functions have been moved toPhoenix.LiveView.Helpers
which can now be fully imported in your views. In other words, replaceimport Phoenix.LiveView, only: [live_render: ..., live_link: ...]
byimport Phoenix.LiveView.Helpers
- Fix bug causing blurred inputs
- Add
Phoenix.LiveComponent
to compartmentalize state, markup, and events in LiveView - Handle outdated clients by refreshing the page with jitter when a valid, but outdated session is detected
- Only dispatch live link clicks to router LiveView
- Refresh the page for graceful error recovery on failed mount when the socket is in a connected state
- Fix
phx-hook
destroyed callback failing to be called in certain cases - Fix back/forward bug causing LiveView to fail to remount
live_isolated
in tests no longer requires a router and a pipeline (it now expects only 3 arguments)- Raise if
handle_params
is used on a non-router LiveView
- [LiveViewTest] Fix function clause errors caused by HTML comments
- Add
phx-debounce
andphx-throttle
bindings to rate limit events
- IE11 support now requires two additional polyfills,
mdn-polyfills/CustomEvent
andmdn-polyfills/String.prototype.startsWith
- Fix IE11 support caused by unsupported
getAttributeNames
lookup - Fix Floki dependency compilation warnings
- [LiveView.Router] Fix module concat failing to build correct layout module when using custom namespace
- [LiveViewTest] Fix
phx-update
append/prepend containers not building proper DOM content - [LiveViewTest] Fix
phx-update
append/prepend containers not updating existing child containers with matching IDs
- [LiveView] Add new
:container
option touse Phoenix.LiveView
- [LiveViewTest] Add
live_isolated
test helper for testing LiveViews which are not routable
- Replace
configure_temporary_assigns/2
with 3-tuple mount return, supporting a:temporary_assigns
key - Do not allow
redirect
/live_redirect
on mount nor in child live views - All
phx-update
containers now require a unique ID LiveSocket
JavaScript constructor now requires explicit dependency injection of Phoenix Socket constructor. For example:
import {Socket} from "phoenix"
import LiveSocket from "phoenix_live_view"
let liveSocket = new LiveSocket("/live", Socket, {...})
- Fix
phx-update=append/prepend
failing to join new nested live views or wire up new phx-hooks - Fix number input handling causing some browsers to reset form fields on invalid inputs
- Fix multi-select decoding causing server error
- Fix multi-select change tracking failing to submit an event when a value is deselected
- Fix live redirect loop triggered under certain scenarios
- Fix params failing to update on re-mounts after live_redirect
- Fix blur event metadata being sent with type of
"focus"
phx-value
has no effect, usephx-value-*
instead- The
:path_params
key in session has no effect (usehandle_params
inLiveView
instead)
- Use optimized
insertAdjacentHTML
for faster append/prepend and proper css animation handling - Allow for replacing previously appended/prepended elements by replacing duplicate IDs during append/prepend instead of adding new DOM nodes
- Fix duplicate append/prepend updates when parent content is updated
- Fix JS hooks not being applied for appending and prepended content
- The LiveView
handle_in/3
callback now receives a map of metadata about the client event - For
phx-change
events,handle_in/3
now receives a"_target"
param representing the keyspace of the form input name which triggered the change - Multiple values may be provided for any phx binding by using the
phx-value-
prefix, such asphx-value-myval1
,phx-value-myval2
, etc - Add control over the DOM patching via
phx-update
, which can be set to"replace"
,"append"
,"prepend"
or"ignore"
phx-ignore
was renamed tophx-update="ignore"