Phoenix.LiveView.Router (Phoenix LiveView v0.16.0) View Source
Provides LiveView routing for Phoenix routers.
Link to this section Summary
Functions
Fetches the LiveView and merges with the controller flash.
Defines a LiveView route.
Defines a live session for live redirects within a group of live routes.
Link to this section Functions
Fetches the LiveView and merges with the controller flash.
Replaces the default :fetch_flash
plug used by Phoenix.Router
.
Examples
defmodule AppWeb.Router do
use LiveGenWeb, :router
import Phoenix.LiveView.Router
pipeline :browser do
...
plug :fetch_live_flash
end
...
end
Defines a LiveView route.
A LiveView can be routed to by using the live
macro with a path and
the name of the LiveView:
live "/thermostat", ThermostatLive
By default, you can generate a route to this LiveView by using the live_path
helper:
live_path(@socket, ThermostatLive)
Actions and live navigation
It is common for a LiveView to have multiple states and multiple URLs. For example, you can have a single LiveView that lists all articles on your web app. For each article there is an "Edit" button which, when pressed, opens up a modal on the same page to edit the article. It is a best practice to use live navigation in those cases, so when you click edit, the URL changes to "/articles/1/edit", even though you are still within the same LiveView. Similarly, you may also want to show a "New" button, which opens up the modal to create new entries, and you want this to be reflected in the URL as "/articles/new".
In order to make it easier to recognize the current "action" your LiveView is on, you can pass the action option when defining LiveViews too:
live "/articles", ArticleLive.Index, :index
live "/articles/new", ArticleLive.Index, :new
live "/articles/:id/edit", ArticleLive.Index, :edit
When an action is given, the generated route helpers are named after the LiveView itself (in the same way as for a controller). For the example above, we will have:
article_index_path(@socket, :index)
article_index_path(@socket, :new)
article_index_path(@socket, :edit, 123)
The current action will always be available inside the LiveView as
the @live_action
assign, that can be used to render a LiveComponent:
<%= if @live_action == :new do %>
<%= live_component MyAppWeb.ArticleLive.FormComponent %>
<% end %>
Or can be used to show or hide parts of the template:
<%= if @live_action == :edit do %>
<%= render("form.html", user: @user) %>
<% end %>
Note that @live_action
will be nil
if no action is given on the route definition.
Options
:container
- an optional tuple for the HTML tag and DOM attributes to be used for the LiveView container. For example:{:li, style: "color: blue;"}
. SeePhoenix.LiveView.Helpers.live_render/3
for more information and examples.:as
- optionally configures the named helper. Defaults to:live
when using a LiveView without actions or defaults to the LiveView name when using actions.:metadata
- a map to optional feed metadata used on telemetry events and route info, for example:%{route_name: :foo, access: :user}
.:private
- an optional map of private data to put in the plug connection. for example:%{route_name: :foo, access: :user}
.
Examples
defmodule MyApp.Router
use Phoenix.Router
import Phoenix.LiveView.Router
scope "/", MyApp do
pipe_through [:browser]
live "/thermostat", ThermostatLive
live "/clock", ClockLive
live "/dashboard", DashboardLive, container: {:main, class: "row"}
end
end
iex> MyApp.Router.Helpers.live_path(MyApp.Endpoint, MyApp.ThermostatLive)
"/thermostat"
Defines a live session for live redirects within a group of live routes.
live_session/3
allow routes defined with live/4
to support
live_redirect
from the client with navigation purely over the existing
websocket connection. This allows live routes defined in the router to
mount a new root LiveView without additional HTTP requests to the server.
Security Considerations
A live_redirect
from the client will not go through the plug pipeline
as a hard-refresh or initial HTTP render would. This means authentication,
authorization, etc that may be done in the Plug.Conn
pipeline must always
be performed within the LiveView mount lifecycle. Live sessions allow you
to support a shared security model by allowing live_redirect
s to only be
issued between routes defined under the same live session name. If a client
attempts to live redirect to a different live session, it will be refused
and a graceful client-side redirect will trigger a regular HTTP request to
the attempted URL.
Note: the live_session is tied to the LiveView and not the browser/cookie
session. Logging out does not expire the live_session, therefore, one should
avoid storing credential/authentication values, such as current_user_id
, in
the live_session and use the browser/cookie session instead.
Options
:session
- The optional extra session map or MFA tuple to be merged with the LiveView session. For example,%{"admin" => true}
,{MyMod, :session, []}
. For MFA, the function is invoked, passing the%Plug.Conn{}
prepended to the arguments list.:root_layout
- The optional root layout tuple for the intial HTTP render to override any existing root layout set in the router.:on_mount
- The optional list of hooks to attach to the mount lifecycle of each LiveView in the session. Passing a single value is also accepted.
Examples
scope "/", MyAppWeb do
pipe_through :browser
live_session :default do
live "/feed", FeedLive, :index
live "/status", StatusLive, :index
live "/status/:id", StatusLive, :show
end
live_session :admin, session: %{"admin" => true}, on_mount: MyAppWeb.LiveAdmin do
live "/admin", AdminDashboardLive, :index
live "/admin/posts", AdminPostLive, :index
end
end
To avoid a false security of plug pipeline enforcement, avoid defining live session routes under different scopes and pipelines. For example, the following routes would share a live session, but go through different authenticate pipelines on first mount. This would work and be secure only if you were also enforcing the admin authentication in your mount, but could be confusing and error prone later if you are using only pipelines to gauge security. Instead of the following routes:
live_session :default do
scope "/" do
pipe_through [:authenticate_user]
live ...
end
scope "/admin" do
pipe_through [:authenticate_user, :require_admin]
live ...
end
end
Prefer different live sessions to enforce a separation and guarantee live redirects may only happen between admin to admin routes, and default to default routes:
live_session :default do
scope "/" do
pipe_through [:authenticate_user]
live ...
end
end
live_session :admin do
scope "/admin" do
pipe_through [:authenticate_user, :require_admin]
live ...
end
end