In this article we talk about getting User Agent inside your LiveView. Fly.io is a great place to run your Phoenix LiveView applications! Check out how to get started!
Here’s a quick recipe. Say your LiveView needs to show something based on the device your user is on such as Mac or Windows. You can parse that from your User Agent header, in fact LiveView already gives you a simple method for that: get_connect_info(socket, :user_agent)
.
The get_connect_info/2
function allows you to retrieve connection information that is only available during the mount lifecycle, such as header or IP information.
Here’s a simple LiveView that just shows your current device based on your user agent. You can use the ua_parser
library to do the weird stuff.
defmodule GetUserAgentWeb.UserAgentLive do
use GetUserAgentWeb, :live_view
def render(assigns) do
~H"""
<div class="text-xl">Device: </div>
"""
end
def mount(_params, _session, socket) do
device =
case UAParser.parse(get_connect_info(socket, :user_agent)) do
%UAParser.UA{device: %UAParser.Device{family: fam}} -> fam
_ -> "I don't know your device"
end
{:ok, assign(socket, device: device)}
end
end
But there’s a catch!
Why your device appears and disappears immediately, you ask? Let’s go through how LiveViews render.
User agents come as HTTP headers so when LiveView first receive an HTTP request that information is already available, the server will reply with a simple HTML response and the device will be rendered. As for WebSockets, they work like this: your browser does a simple HTTP request to a server but the server replies telling that this request will be upgraded to an WebSocket.
During the socket upgrade you lose your User Agent—The WebSocket connection doesn’t carry this info—so this second render clears the device value from the screen. You need to tell Phoenix to store it under your socket state so you can use it later. Go to your endpoint.ex
file and let’s edit it a little bit:
- socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [session: @session_options]]
+ socket "/live", Phoenix.LiveView.Socket, websocket: [connect_info: [:user_agent, session: @session_options]]
You just added :user_agent
to the WebSocket config and now everything should just work! Don’t forget to restart your server; endpoint.ex
doesn’t get reloaded automatically.