benmacha / mousetracker
Self-hosted mouse, click and scroll tracker for Symfony. Mouseflow-style heatmaps and session replay.
Package info
github.com/BenMacha/mouseTracker
Language:JavaScript
Type:symfony-bundle
pkg:composer/benmacha/mousetracker
Requires
- php: >=8.1
- doctrine/doctrine-bundle: ^2.10
- doctrine/orm: ^2.14|^3.0
- doctrine/persistence: ^3.0|^4.0
- symfony/config: ^5.4|^6.4|^7.0
- symfony/dependency-injection: ^5.4|^6.4|^7.0
- symfony/framework-bundle: ^5.4|^6.4|^7.0
- symfony/http-foundation: ^5.4|^6.4|^7.0
- symfony/http-kernel: ^5.4|^6.4|^7.0
- symfony/routing: ^5.4|^6.4|^7.0
- symfony/yaml: ^5.4|^6.4|^7.0
- twig/twig: ^3.0
Requires (Dev)
- phpstan/phpstan: ^2.0
- phpstan/phpstan-doctrine: ^2.0
- phpstan/phpstan-symfony: ^2.0
- phpunit/phpunit: ^9.6|^10.5|^11.0
- symfony/browser-kit: ^5.4|^6.4|^7.0
- symfony/css-selector: ^5.4|^6.4|^7.0
- symfony/dom-crawler: ^5.4|^6.4|^7.0
- symfony/phpunit-bridge: ^5.4|^6.4|^7.0
- symfony/twig-bundle: ^5.4|^6.4|^7.0
- symfony/var-exporter: ^6.4|^7.0
This package is auto-updated.
Last update: 2026-06-03 04:15:56 UTC
README
Self-hosted mouse, click and scroll tracker for Symfony 5.4 / 6.4 / 7.x. Captures mousemoves, clicks, scroll positions, form-blur values and DOM snapshots, then ships them to your own database for Mouseflow-style heatmaps and session replay. No jQuery.
Requirements
| Package | Version |
|---|---|
| PHP | >=8.1 |
| Symfony | ^5.4 | ^6.4 | ^7.0 |
| Doctrine ORM | ^2.14 | ^3.0 |
Installation
composer require benmacha/mousetracker:^2.0
If you don't use Symfony Flex, register the bundle in config/bundles.php:
return [ // ... benmacha\mousetracker\TrackerBundle::class => ['all' => true], ];
Routing
config/routes/mouse_tracker.yaml:
mouse_tracker: resource: '@TrackerBundle/Resources/config/routes.yaml' prefix: /tracker
Configuration (optional)
config/packages/mouse_tracker.yaml:
mouse_tracker: record_click: true record_move: true record_keyboard: true percentage_recorded: 100 disable_mobile: false ignore_ips: []
Database
php bin/console doctrine:schema:update --force
# or, with migrations:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
This creates three tables: tracker__client, tracker__page, tracker__data.
Publish assets
php bin/console assets:install --symlink public/
Copies the tracker JavaScript to public/bundles/tracker/js/tracker.js.
Usage
Inject the tracker snippet right before the closing </body> tag of any page you want to record:
{# templates/base.html.twig #} {{ mouse_tracker_service.build()|raw }} </body> </html>
Expose the service as a Twig global in config/packages/twig.yaml:
twig: globals: mouse_tracker_service: '@mouse_tracker'
That's it — the tracker boots on DOMContentLoaded and starts batching events to /tracker/createClient and /tracker/addData.
Backend (replay UI)
The bundle ships a basic backend at /tracker/back/ for listing sessions and replaying recordings.
⚠️ Security — read this before deploying. The
/tracker/back/*routes (replay UI +getPages/getClients/getDataJSON endpoints) are public by default. Anyone who can reach your app can browse every recorded session, including form values, click coordinates, and DOM snapshots — which often contain PII.Gate them behind your
security.yamlfirewall before you ship. Example:# config/packages/security.yaml security: access_control: - { path: ^/tracker/back, roles: ROLE_ADMIN } # the ingest endpoints below must stay reachable from the public site - { path: ^/tracker, roles: PUBLIC_ACCESS }The same goes for GDPR/consent:
/tracker/createClientand/tracker/addDataare intentionally public so the tracker can post from any page, but you are responsible for getting visitor consent before loadingtracker.js.
Settings
Client-side settings are forwarded from PHP config into a window.MouseTrackerConfig.settings blob. You can also override them after the script loads via UST.settings:
<script> window.UST && (UST.settings.delay = 100); </script>
| Key | Default | Description |
|---|---|---|
record_click |
true |
Record left/right clicks |
record_move |
true |
Record mousemove heatmap data |
record_keyboard |
true |
Capture input/textarea values on blur (never password) |
percentage_recorded |
100 |
% of visitors to sample |
disable_mobile |
false |
Skip recording on mobile UAs |
ignore_ips |
[] |
IP allowlist via l2.io/ip.js (opt-in) |
Upgrading from 1.x
v2 is a breaking rewrite. See CHANGELOG.md for the migration path. Highlights:
- Drops Symfony 2.8, Assetic, Sensio Framework Extra Bundle, jQuery
- Doctrine/route annotations replaced with PHP 8 attributes
services.yml→services.yaml; newroutes.yamlresourcemousetrackerServiceglobal →mouse_tracker_service- Tracker JS is now plain vanilla — no jQuery to load first
License
MIT — see Resources/meta/LICENSE.