We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Add query params to Phoenix verified routes with `~p`
almirsarajcic
Phoenix verified routes handle query parameters with the same ~p sigil you use for paths. Pass a map or keyword list after ?#{} and get compile-time verification plus automatic URL encoding.
# Pass maps or keyword lists after ?#{}
params = %{page: 1, sort: "name", filter: "active"}
~p"/users?#{params}"
# => "/users?filter=active&page=1&sort=name"
# Inline keyword list works too
~p"/search?#{[q: "elixir phoenix", limit: 10]}"
# => "/search?limit=10&q=elixir+phoenix"
# Single values interpolate directly
page = 3
~p"/posts?page=#{page}"
# => "/posts?page=3"
The params are automatically URL-encoded (spaces become +) and sorted alphabetically. The sorting helps with test assertions - comparing URLs works regardless of param order.
Conditional params
Build dynamic query strings by filtering empty values:
def build_search_url(query, filters) do
params =
[q: query, category: filters[:category], sort: filters[:sort]]
|> Enum.reject(fn {_k, v} -> is_nil(v) or v == "" end)
~p"/search?#{params}"
end
build_search_url("elixir", %{category: "books"})
# => "/search?category=books&q=elixir"
build_search_url("elixir", %{})
# => "/search?q=elixir"
LiveView navigation
Query params work seamlessly with push_patch and push_navigate:
def handle_event("filter", %{"status" => status}, socket) do
params = %{status: status, page: 1}
{:noreply, push_patch(socket, to: ~p"/orders?#{params}")}
end
def handle_event("search", %{"q" => query}, socket) do
{:noreply, push_navigate(socket, to: ~p"/results?#{[q: query]}")}
end
Empty params edge case
When params might be empty, use a conditional:
# Avoid ~p"/users?#{[]}" which produces "/users?"
def list_url(filters) when filters == %{}, do: ~p"/users"
def list_url(filters), do: ~p"/users?#{filters}"
# Or inline with if
~p"/users#{if params != %{}, do: "?#{params}", else: ""}"
Links
copied to clipboard
Comments (0)
Sign in with GitHub to join the discussion