PhoenixKitWebAnalytics (PhoenixKitWebAnalytics v0.5.0)

Copy Markdown View Source

Web analytics for PhoenixKit sites, recorded by the server — who comes, where from, what they do, and when they leave.

Where the data comes from

No cookie, no IP address, no raw User-Agent and no query string is stored; visitors are a salted daily hash — see PhoenixKitWebAnalytics.Visitor.

Reports and alerts

Admin pages: overview, right now, sessions with a per-visit timeline, pages, acquisition, technology, events, settings. Everything they show comes from PhoenixKitWebAnalytics.Reports, a plain module you can call:

alias PhoenixKitWebAnalytics.Reports

Reports.top_paths(Reports.filter(period: "30d"), limit: 20)

PhoenixKitWebAnalytics.Alerts registers a "Website activity" notification type — new visitors (filtered), sign-ups, tracked events — delivered through PhoenixKit's notification channels (in-app, email, Telegram, digests).

Installation

# host mix.exs
{:phoenix_kit_web_analytics, "~> 0.2"}

Then mix deps.get and mix phoenix_kit.update, add the plug and the hook, list :peer_data, :x_headers and :user_agent in the LiveView socket's connect_info (websocket and longpoll), and enable the module on the admin Modules page.

Data growth

PhoenixKitWebAnalytics.Retention rolls completed days into daily totals and prunes raw events past the retention window (365 days by default), so the trend line is permanent while the row count is bounded.

Summary

Functions

Sidebar entries. Routes come from route_module/0, so no tab carries a :live_view — these are navigation and active-state anchors only.

Background workers: the task supervisor that absorbs writes off the request path, and the hourly rollup/prune pass — plus a one-off check of the application config, logged once as the module starts.

Turns tracking on, generating the visitor-hash salt if this is a first enable — so the very first request already hashes against a real secret.

Whether tracking is on.

Summary shown on the admin Modules page.

The optional client script (clicks the server can't see, scroll depth, exits from non-LiveView pages), folded into the host's phoenix_kit_modules.js. It sends nothing the server accepts until Client script is switched on in settings.

The events + daily stats tables (run by mix phoenix_kit.update).

The Website activity notification type — new visitors, sign-ups and tracked events. See PhoenixKitWebAnalytics.Alerts.

The admin pages plus the public collection endpoints.

Records a custom event from server-side code.

Records a page view from server-side code.

Functions

admin_tabs()

Sidebar entries. Routes come from route_module/0, so no tab carries a :live_view — these are navigation and active-state anchors only.

children()

Background workers: the task supervisor that absorbs writes off the request path, and the hourly rollup/prune pass — plus a one-off check of the application config, logged once as the module starts.

enable_system()

Turns tracking on, generating the visitor-hash salt if this is a first enable — so the very first request already hashes against a real secret.

enabled?()

Whether tracking is on.

Defensive against the DB being unavailable (boot ordering, a test sandbox owner that just stopped): every failure path answers false, so the plug treats "we don't know" as "don't track".

get_config()

Summary shown on the admin Modules page.

js_sources()

The optional client script (clicks the server can't see, scroll depth, exits from non-LiveView pages), folded into the host's phoenix_kit_modules.js. It sends nothing the server accepts until Client script is switched on in settings.

migration_module()

The events + daily stats tables (run by mix phoenix_kit.update).

notification_types()

The Website activity notification type — new visitors, sign-ups and tracked events. See PhoenixKitWebAnalytics.Alerts.

route_module()

The admin pages plus the public collection endpoints.

track_event(name, attrs \\ %{})

@spec track_event(String.t(), map()) :: :ok

Records a custom event from server-side code.

Use this for things that happen in your context modules rather than in the browser — an order placed, a subscription upgraded — where the event is a fact the server already knows and shouldn't depend on the client to report.

PhoenixKitWebAnalytics.track_event("order.placed", %{
  path: "/checkout",
  metadata: %{"total_cents" => 4900},
  user_uuid: user.uuid
})

attrs accepts any key from PhoenixKitWebAnalytics.Collector's hit shape. Returns :ok immediately; the write happens in a supervised task.

Without :ip and :user_agent the event still records, but under a visitor hash that won't match that person's page views — pass conn values through when the event happens inside a request and you want it attributed to the same visitor.

track_pageview(attrs)

@spec track_pageview(map()) :: :ok

Records a page view from server-side code.

Only needed for pages the plug can't see — a response rendered by something other than the browser pipeline. Ordinary pages are already counted.