2026-03-206 phút đọcVI
Session Replay — Watching Real Users
Mở đầu
Heatmaps cho biết "users click ở đâu." Funnel analysis cho biết "bao nhiêu % users hoàn thành." Nhưng không gì thay thế việc xem thực tế user dùng site — mouse di chuyển thế nào, scroll đến đâu, bị stuck ở đâu, bỏ đi khi nào.
Session Replay là PostHog's killer feature. Nó record lại toàn bộ user session — mouse movement, scrolls, clicks, page navigation — dưới dạng video anh có thể xem lại. Không phải screen recording (video nặng) — PostHog dùng DOM snapshot + mutations (nhẹ, efficient).
Mục tiêu: Hiểu cách Session Replay hoạt động, privacy controls trên leduykhuong.com, và cách extract UX insights.
Cách hoạt động — DOM Replay, không phải Video
Session Replay KHÔNG record video pixels. Nó:
- Snapshot DOM lúc page load — capture full HTML tree
- Record mutations — DOM changes (class toggle, text update, element add/remove)
- Record events — mouse position (x, y), clicks, scrolls, page navigations
- Gửi data lên PostHog server
- Replay bằng cách rebuild DOM + replay events → trông như video nhưng thực chất là DOM reconstruction
Ưu điểm:
- Data nhỏ hơn video ~100x (text-based, không phải pixels)
- Có thể inspect elements trong replay (click vào element → xem selector)
- Không capture nội dung bị masked (privacy)
Configuration trên leduykhuong.com
// components/analytics/PostHogProvider.tsx
posthog.init(POSTHOG_KEY, {
// ...
session_recording: {
maskAllInputs: true, // Mask all <input> elements
},
});Privacy Controls
| Setting | Giá trị | Ý nghĩa |
|---|---|---|
maskAllInputs | true | Che tất cả form inputs (search, etc.) |
maskTextSelector | (default) | Không mask text mặc định |
blockSelector | (not set) | Không block element nào |
maskAllInputs: true — Trong session replay, mọi <input> value hiển thị là ***. User gõ search query → replay chỉ thấy ***. Đây là privacy-first approach:
- Không record passwords
- Không record search queries (có thể chứa personal info)
- Không record form data
Nếu cần mask thêm:
session_recording: {
maskAllInputs: true,
maskTextSelector: ".sensitive-text", // Mask text content of specific elements
blockSelector: ".no-record", // Completely exclude elements from recording
}Xem Session Replay
PostHog Dashboard → Session Replay:
Replay Player Interface
┌─────────────────────────────────────────────────┐
│ ▶ Play ⏸ Pause 1x Speed [Timeline] │
│ │
│ ┌───────────────────────────────────────────┐ │
│ │ │ │
│ │ [Reconstructed page] │ │
│ │ Mouse cursor: ⊕ (moves in real-time) │ │
│ │ Clicks: highlighted with pulse animation │ │
│ │ Scrolls: page scrolls │ │
│ │ │ │
│ └───────────────────────────────────────────┘ │
│ │
│ Events timeline: ●──●───●─●──────●──● │
│ pv click scroll pv │
│ │
│ Duration: 3m 45s | Pages: 4 | Events: 23 │
└─────────────────────────────────────────────────┘
Filter Sessions
Không cần xem tất cả — filter for interesting sessions:
| Filter | Khi nào dùng |
|---|---|
| Duration > 2 min | Long sessions (engaged users) |
| Duration < 15 sec | Bounce sessions (frustrated users) |
Visited URL contains /blog/ | Blog readers only |
Event = search_used | Users who searched |
| Frustration signals | Rage clicks, U-turns |
Frustration Signals
PostHog auto-detect frustration patterns:
- Rage clicks — User click cùng chỗ 3+ lần nhanh (element không respond)
- Dead clicks — Click vào nơi không có interactive element
- U-turns — Navigate forward rồi immediately back
- Thrashing — Mouse di chuyển nhanh, không mục đích
UX Insights — Cách extract giá trị
Pattern 1: Navigation Confusion
Observation: 5/10 users click vào tag pill rồi immediately back. Insight: Tag page content không match expectation. Users expect more articles, thấy ít hoặc không đúng. Action: Improve tag pages hoặc set minimum post count trước khi hiển thị tag.
Pattern 2: Search Discovery
Observation: Users scroll lên xuống blog listing 3-4 lần trước khi tìm thấy bài. Insight: Blog listing thiếu search functionality visible. Users cần tìm kiếm nhưng không thấy search bar. Action: Make search more prominent (sticky header, search icon).
Pattern 3: Reading Depth
Observation: Users đọc 70% bài rồi dừng tại code example. Insight: Code example quá dài hoặc phức tạp → users skip hoặc abandon. Action: Simplify code examples, add explanations, break into smaller chunks.
Pattern 4: Mobile UX
Observation: Mobile users struggle tap TOC links (too close together). Insight: Touch targets quá nhỏ. Action: Increase spacing giữa TOC items trên mobile.
Session Replay + Events — Combining Context
PostHog cho phép filter replay theo events:
Show me sessions where:
- User triggered "search_used"
- AND visited > 3 pages
- AND duration > 2 minutes
→ Xem HOW engaged users dùng search → learn patterns để optimize cho other users.
Hoặc:
Show me sessions where:
- User visited /vi/blog/data-as-product
- AND bounced (1 page only)
→ Xem WHY users bounce từ bài cụ thể → maybe content doesn't match title? Maybe page load chậm?
Performance Impact
Session Replay thêm ~15-30KB initial load (PostHog SDK) + continuous data gửi lên server. Impact:
| Metric | Without PostHog | With PostHog |
|---|---|---|
| JS bundle | ~200KB | ~230KB |
| Network requests | N | N + recording data |
| LCP | ~1.2s | ~1.3s |
| Memory | Normal | +5-10MB |
Mitigation trên leduykhuong.com:
- Production only —
AnalyticsProvidergate = không load trên dev afterInteractivestrategy — GA4 load after interactive- PostHog lazy load — PostHog init trong
useEffect(sau hydration)
Free Tier Limits
PostHog free tier: 5,000 session recordings/month. Với leduykhuong.com (~500-1000 sessions/month), thoải mái dùng.
Nếu traffic tăng, PostHog cho phép sampling:
posthog.init(POSTHOG_KEY, {
session_recording: {
sample_rate: 0.5, // Record 50% of sessions
},
});Thực hành
Bài tập 1: Xem session replay
Mở PostHog → Session Replay:
- Xem 3 sessions ngẫu nhiên
- Ghi nhận: users navigate thế nào? Họ click gì? Bỏ đi ở đâu?
Bài tập 2: Filter frustrated users
Filter: sessions với rage clicks hoặc duration < 15s:
- Xem 2-3 sessions
- Câu hỏi: Frustration xảy ra ở đâu? Element nào gây confusion?
Bài tập 3: Blog reading pattern
Filter: sessions visiting /blog/* với duration > 2 min:
- Users scroll đến đâu?
- Có dừng lại đọc code examples không?
- TOC được dùng không?
Tóm tắt
- Session Replay = DOM reconstruction, không phải video recording → nhẹ, privacy-friendly
maskAllInputs: true— Che tất cả form inputs trong replay- Frustration signals — PostHog auto-detect rage clicks, dead clicks, U-turns
- UX insights — Xem actual user behavior → discover navigation confusion, reading patterns, mobile issues
- Events + Replay — Filter sessions theo events để xem behavior in context
- Free tier — 5,000 recordings/month, thừa cho personal blog
Bài tiếp theo
Bài 15: Funnels & User Paths — Vẽ user journey: Blog landing → Click bài → Đọc xong → Click bài tiếp. Bao nhiêu % users hoàn thành mỗi step?