A repository of bitesize articles, tips & tricks
(in both English and French) curated by Mirego’s team.

Leveraging LiveView lifecycle hooks to send contextual data to Google Tag Manager

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](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.html#attach_hook/4) 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.