Open source · Rack-compatible · Privacy-first

See what your users see.
Respect what they don't share.

Sentiero is an open-source session recording gem for Ruby. Drop it into any Rack app (Rails, Sinatra, Hanami, Roda) and understand your users without compromising their privacy.

Sentiero session replay dashboard: rrweb playback with a color-coded event timeline and activity sidebar

Session replay in the built-in dashboard: timeline, activity sidebar, and Web Vitals.

Works with Ruby on Rails Sinatra Hanami Roda ...any Rack app
Core Features

A complete session recording toolkit

Self-hosted, framework-agnostic, and genuinely free. No artificial limits, no data leaves your servers.

Session Recording

Full DOM recording powered by rrweb. Captures clicks, scrolls, navigations, and DOM mutations. Events are gzip-compressed, batched (time and count thresholds), and retried automatically on network failure.

Replay Dashboard

Built-in admin viewer mounts inside your app. Browse and search sessions, replay with activity sidebar, color-coded event timeline, playback speed (1x to 16x), keyboard shortcuts, and multi-window tab switching.

Per-Session Heatmaps

Click positions rendered spatially on the DOM snapshot during replay. Scroll depth indicator shows how far the user scrolled. All computed client-side from loaded events, no extra server cost.

Custom Event Tracking

Track specific interactions with window.Sentiero.addCustomEvent() or declarative data-sentiero-track-* HTML attributes. Supports click, change, submit, focus, and blur events with optional JSON payloads.

Error Capture

Opt-in recording of JavaScript errors and unhandled promise rejections. Errors appear as markers in the replay timeline at the exact moment they occurred, with message, source file, line number, and stack trace.

Opt-in

Pluggable Storage

Memory store for development. Redis with sorted sets and optional TTL for production. ActiveRecord for Rails apps. Or implement the store interface and bring your own backend. Configurable resource limits prevent unbounded growth.

Also included

Cross-tab sessions JSON export Deep links with timestamp Session metadata capture Navigation tracking sendBeacon on page close Dashboard authentication CSRF protection CSP headers CORS whitelisting MIT licensed Cross-session analytics Conversion funnels Form analytics Session segmentation Shareable HTML replays Analytics export (CSV/JSON)
Cross-session analytics · included

See patterns, not just sessions

Aggregate insight across every recorded session, computed on your own server and shipped in the open-source gem. No separate tier.

Aggregate heatmaps

Click density across all sessions for a page, attributed per URL so multi-page sessions don't blur together.

Scroll depth

Per-page scroll-depth distribution with fold lines, so you can see how far visitors actually get.

Form analytics

Field-level interaction and drop-off, with human-readable field labels resolved from the DOM. Values stay masked.

Conversion funnels

Chain custom events into a funnel and watch where users fall out, step by step.

Segmentation

Filter sessions by browser, device, URL, metadata, error presence, or duration, and combine filters freely.

Export & shareable replays

CSV/JSON export of analytics data, plus self-contained HTML replays you can attach to a bug report. No server needed.

Conversion funnel with per-step drop-off and median timings
Privacy by Design

Privacy isn't a feature.
It's the foundation.

Privacy-conscious defaults out of the box. All form inputs are masked. Password masking is enforced at the code level and cannot be disabled. Anything potentially invasive must be explicitly enabled by you.

All form inputs masked by default

Values typed into text fields, textareas, and selects are replaced with asterisks before reaching the server. Password masking is hardcoded in both Ruby and JavaScript and cannot be overridden.

Per-element recording control

Block entire sections with data-rr-block, mask text with data-rr-mask, or ignore mutations with data-rr-ignore. Selectively unmask specific inputs with data-sentiero-unmask when needed.

Invasive features are opt-in only

Error capture, navigation tracking, metadata collection, and custom event tracking are all off by default. Enable them individually as needed.

Self-hosted, no data leaves your server

No third-party data processors, no SaaS middlemen, no phone-home. Your data stays in your infrastructure. GDPR compliance is simpler when you're both controller and processor.

User opt-out and signal respect

Built-in helpers let users disable recording. Global Privacy Control is supported and respected by default: the recorder reads navigator.globalPrivacyControl client-side, so if a browser signals "don't track me," the recorder won't start.

PRIVACY BY DEFAULT No tracking without consent
GDPR-friendly
First-party cookies only
Quick Start

Up and running in under a minute

1 Add to your Gemfile
# Gemfile
gem "sentiero-rails"
2 Run the install generator
$ bundle install
$ rails generate sentiero:install
$ rails db:migrate
3 Mount the routes
# config/routes.rb
mount Sentiero::Web::EventsApp.new => "/sentiero/events"
mount Sentiero::Web::DashboardApp.new => "/sentiero"
4 Add the recorder to your layout
<%# app/views/layouts/application.html.erb %>
<%= sentiero_script_tag %>

Using Roda, Sinatra, or plain Rack? The core sentiero gem works with any Rack-compatible framework. See the docs for framework-specific setup.

Free means free. No tricks.

The community edition is MIT-licensed and feature-complete. It is not a trial, not a demo, and not a crippled version of a paid product. Session recording, replay, heatmaps, custom events, error capture, privacy controls, and export all ship in the open-source gem, with no artificial limits.

No feature gates

Every recording, replay, and privacy feature works without a license key, usage cap, or time limit. Free forever, in production, with no paywalled features.

Community-driven

Bug fixes, features, and security patches happen in the open. Contributions are welcome. The roadmap reflects what users actually need.

Analytics included

Cross-session analytics (heatmaps, scroll depth, form analytics, conversion funnels, and segmentation) ship in the gem. No tier, no license key, no usage cap.

How it compares

Where Sentiero fits

Two questions most people have. Here are the honest answers.

vs. raw rrweb

rrweb is the in-browser record and replay primitive. Sentiero builds the whole product around it: transport, storage, a replay dashboard, cross-session analytics (funnels, frustration signals, engagement, Web Vitals, conversions), and error tracking.

The bigger gap is privacy. rrweb gives you masking primitives; Sentiero adds a real privacy layer on top: enforced password masking, mask-all-inputs by default, Global Privacy Control respected by default, user opt-out, server-side sanitizers, IP anonymization, and retention plus erasure tooling.

Transport & storage Replay dashboard Cross-session analytics Error tracking Privacy layer

vs. Hotjar & SaaS tools

Hosted tools are quick to switch on, but your session data lives on someone else's servers and pricing scales with seats and sessions. Sentiero is self-hosted and embeddable: it mounts inside your own Ruby app, so recordings never leave your infrastructure.

It is open source and free with no seat caps, no session caps, and no paywalled features. The honest tradeoff: you run and scale it yourself, on the storage backend you already operate.

Self-hosted Data stays with you No seat or session caps Open source You run it yourself

Start understanding your users.
Without selling them out.

Add Sentiero to your Gemfile, mount the routes, and you're recording sessions in under a minute. Free, open source, privacy-first.