Guides

User journey analysis from session events

By · updated

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.pricing and page.view.home are different steps. A bare page_view for 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/12345 as its own step gives every product its own node. Map routes to a pattern with pageNameFn and 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.request without user.signup.success is a failure visible in the matrix without any extra instrumentation.
  • Error states. A .failure action 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

  1. Make page identity part of the action name.
  2. Name custom events as a hierarchy, outcome last.
  3. Map identifier-carrying routes to patterns.
  4. Read top exits weekly.
  5. Encode each funnel step as a tested rule.
  6. Inspect individual sessions behind any change.

Start with the quickstart.