Google Tag Manager is a popular tool for receiving tracking events from your web application. Sometimes, you will use it to send specific behavioral data (i.e., when the user uses a dropdown to change the status of a task, we send the old status and the new status). Other times, you will track more common actions (i.e., navigating to a page).
And in all these cases, you will probably want some general information about the current state of your application or the user performing the actions.
In a Phoenix LiveView application, one way to attach this general information to every event performed in your web application is to use LiveView lifecycle hooks with attach_hook and a custom event:
In the view referencing your global layouts (i.e., app_html.ex
), we create the after-render hook:
def on_mount(:attach_user_properties_to_analytics, _params, _session, socket) do
{:cont, Phoenix.LiveView.attach_hook(socket, :user_analytics, :after_render, &after_render("attach_user_properties_to_analytics", &1))}
end
defp after_render("attach_user_properties_to_analytics", %{assigns: %{user: user}} = socket) do
Phoenix.LiveView.push_event(socket, "init-datalayer-user-properties", %{
role: user.role
})
end
In the router, we reference the previously created on_mount
hook:
scope "/app", as: :app do
pipe_through [:browser, :auth]
live_session :require_app_user,
layout: {Demo.App.AppHTML, :main},
on_mount: [
{Demo.UserAuth, :ensure_authenticated},
{Demo.App.AppHTML, :attach_user_properties_to_analytics}
] do
[... your routes]
end
end
In app.ts
, we are pushing the data to the GTM data layer when we receive the event:
window.addEventListener('phx:init-datalayer-user-properties', ({detail: detail}) => {
window.dataLayer.push({
event: 'user-properties',
role: detail.role
});
});
That’s it! Every time the LiveView application renders a new page, the GTM data layer will be updated, and subsequent events will now have this information attached to them.