We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
When using Phoenix LiveView, you might need to get the current URL in any part of the application.
A common use-case is a layout where you show a navigation menu highlighting the current section based on the URL path.
To do this in an elegant way, you can start with defining a LiveHooks
module which looks like this:
defmodule MyAppWeb.LiveHooks do
import Phoenix.Component, only: [assign: 3]
import Phoenix.LiveView, only: [attach_hook: 4]
# Define a hook called :global
def on_mount(:global, _params, _session, socket) do
# Attach a hook on mount which gets the current path
{:cont,
socket
|> attach_hook(:assign_current_path, :handle_params, &assign_current_path/3)}
end
defp assign_current_path(_params, url, socket) do
# Parse the current path
uri = URI.parse(uri) |> current_path()
# Assign the current path in the socket
{:cont,
socket
|> assign(:current_path, uri)}
end
# Get the current path with the query string is present
defp current_path(%URI{} = uri) when is_binary(uri.path) and is_binary(uri.query) do
uri.path <> "?" <> uri.query
end
# Get the curretn path if no query string is present
defp current_path(%URI{:path => path}), do: path
end
Once the module exists, we can attach it to the live_session
in on_mount
:
live_session :app,
# Call the global hook on mount
on_mount: [
{MyAppWeb.LiveHooks, :global}
] do
live "/", HomeLive.Index, :home
end
After updating the live_session
, all the children of that session will now have access to the current path:
{@current_path}
If you want more flexibility, you can also store the complete URL in the assignments. However, since I'm only interested in the path itself with the query string, I'm first parsing the URL and I'm storing only what I really need.
If this post was enjoyable or useful for you, please share it! If you have comments, questions, or feedback, you can email my personal email. To get new posts, subscribe use the RSS feed.