User journey analysis from session events
User journey analysis asks what people do on your site, in what order, and where they stop. Most tools answer it by asking you to define a funnel first. This guide works the other way: record every step as a structured event, group the steps into sessions, and let the journeys show themselves.
The examples use Clientlog, and the method applies to any event data with a session identifier and an order.
Start with the unit
A journey belongs to a session: one visit, its events in order, with timings. Page views are the wrong unit, because a page view has no before or after. A user is the wrong unit for most sites, because linking visits needs an identifier that persists, and with it a consent prompt.
A Clientlog session summary carries the journey directly:
page.view.home 0
page.scroll.home 8400
page.exit.home 12100
page.view.pricing 12200
page.scroll.pricing 19000
page.exit.pricing 47200
Each line is an action and its offset in milliseconds from the start of the session.
Name events so journeys are readable
Journey analysis is only as good as the action names. Three rules:
- Put the page in the name.
page.view.pricingandpage.view.homeare different steps. A barepage_viewfor every page collapses every journey into one node. The Clientlog client does this by default. - Name custom events as a hierarchy.
user.signup.request,user.signup.success,user.signup.failure. The prefix groups a feature; the last segment states the outcome. - Keep identifiers out of names.
/products/12345as its own step gives every product its own node. Map routes to a pattern withpageNameFnand put the identifier in the payload.
The full convention is in events.
The transition matrix
Count, across every session in a window, how often each action is followed by each other action. The result is a transition matrix: rows are where visitors are, columns are where they go next, and one column is the exit.
From that matrix:
- Top landings are the actions that most often start a session.
- Top exits are the actions most often followed by nothing.
- Top paths are the most frequent sequences.
Top landings: page.view.home (38), page.view.pricing (19)
Top exits: page.view.pricing (22), page.view.home (17)
Top paths: page.view.home -> page.view.pricing -> [exit] (14)
The weekly digest carries this summary. The full matrix is available through the API and as a graph in the dashboard.
To compute one on demand:
clientlog trigger transitions --hours 168 --min-sessions 2
Finding drop-off
A drop-off point is an action that appears often as an exit and rarely as a step towards anything else. The places to look:
- The pricing page. Many arrivals and many exits with short dwell time is a page that answers no questions.
- The middle of a form.
user.signup.requestwithoutuser.signup.successis a failure visible in the matrix without any extra instrumentation. - Error states. A
.failureaction followed by an exit is a bug report you did not receive.
Each automatic page.exit event carries dwell_ms and max_scroll, so an
exit can be read as “left after reading”, or “left without scrolling”.
Turn journey steps into rules
A funnel step becomes a rule that tags the session, and tags are counted in every digest:
rules:
- rule_id: reached_pricing
tag: pricing
logic: {"in": ["page.view.pricing", {"var": "session.actions"}]}
- rule_id: read_pricing
tag: pricing_read
requires_events: true
description: Scrolled most of the pricing page
logic:
{"some": [{"var": "events"},
{"and": [
{"==": [{"var": "action"}, "page.scroll.pricing"]},
{">=": [{"var": "payload.percent"}, 75]}
]}]}
- rule_id: signed_up
tag: converted
logic: {"in": ["user.signup.success", {"var": "session.actions"}]}
The ratios between tags are the funnel: sessions that reached pricing, read it, and converted. The rules live in your repository and are tested before they deploy. See rules.
Looking at single journeys
Aggregates show where to look. Individual sessions show what happened:
clientlog sessions list --limit 50
clientlog sessions events --session-id 1782693098872-7xzwuxbzd
The llm output format renders a set of sessions as a compact summary with
one line per journey, sized to paste into a language model with a question:
clientlog --format llm sessions list --limit 50
Customer journey analysis across visits
Linking journeys across visits needs an identifier that persists, such as a
signed-in account. Clientlog’s sessionIdFn option groups events by an
identifier you supply. That introduces identity linkage, and with it the
lawful basis and privacy notice obligations covered on the
privacy page. For anonymous visitors, each visit stays a
separate journey.
Checklist
- Make page identity part of the action name.
- Name custom events as a hierarchy, outcome last.
- Map identifier-carrying routes to patterns.
- Read top exits weekly.
- Encode each funnel step as a tested rule.
- Inspect individual sessions behind any change.
Start with the quickstart.