A real-time DOM element visibility tracking system with React components and WebSocket server.
Element Tracker provides a complete solution for tracking user interactions with DOM elements in web applications. It consists of React components that monitor element visibility and a WebSocket server that collects and stores this data in MongoDB.
- π Real-time element visibility tracking using Intersection Observer API
- π Automatic reconnecting WebSocket connections
- π Google OAuth integration for user identification
- π± Support for both IPv4 and IPv6 client identification
- ποΈ MongoDB storage for tracking data
- β‘ Throttled updates to optimize performance
- π Automatic hash navigation based on active elements
- π³ Docker support for easy deployment
This monorepo contains four packages:
types- Shared TypeScript types with runtime validationreact- React hooks and components for client-side trackingserver- Koa.js WebSocket server for data collectiondemo- Next.js demonstration application
# Clone the repository
git clone https://github.com/your-org/element-tracker.git
cd element-tracker
# Install dependencies
npm install
# Build all packages
npm run build --workspacesnpm run backend
# or
docker-compose upCreate .env.development in the server directory:
MONGODB=mongodb://localhost:27017/elementTracker
GOOGLE_CLIENT_IDS=your-client-id-1,your-client-id-2
VALID_DOMAINS=http://localhost:3000,https://yourdomain.com
SECRET=your-encryption-secretcd server
npm startcd demo
npm startimport { ElementTrackerServer, ElementTracker } from "@cs124/element-tracker"
function App() {
return (
<ElementTrackerServer
server="ws://localhost:8080"
googleToken={userGoogleToken}
>
<ElementTracker>
<div data-et="true" data-et-id="section-1">
<h1>Tracked Content</h1>
<p>This element's visibility will be tracked</p>
</div>
</ElementTracker>
</ElementTrackerServer>
)
}data-et="true"- Mark an element for trackingdata-et-id="custom-id"- Set a custom ID (falls back to element'sidattribute)
The server exposes a WebSocket endpoint at / that accepts:
Connection Query Parameters:
browserID- Unique browser identifiertabID- Unique tab identifier
Message Types:
- Login Message
{
"type": "login",
"googleToken": "oauth-token"
}- Update Message
{
"type": "update",
"location": "current-url",
"width": 1920,
"height": 1080,
"elements": [
{
"tagName": "div",
"top": 100,
"bottom": 200,
"id": "section-1",
"text": "Content text"
}
]
}# Type checking
npm run tsc
# Linting
npm run eslint
# Code formatting
npm run prettier
# Run all checks
npm run check
# Update dependencies
npm run ncu# Build all packages
npm run build --workspaces
# Build specific package
cd types && npm run buildRun the demo application to test the tracking functionality:
cd demo
npm start| Variable | Description | Default |
|---|---|---|
MONGODB |
MongoDB connection string | Required |
MONGODB_COLLECTION |
Collection name | elementTracker |
GOOGLE_CLIENT_IDS |
Comma-separated OAuth client IDs | Optional |
VALID_DOMAINS |
Comma-separated allowed origins | Optional |
SECRET |
Encryption key for session tokens | Optional |
SECURE_COOKIE |
Use secure cookies | false |
| Prop | Type | Description | Default |
|---|---|---|---|
server |
string |
WebSocket server URL | Required |
googleToken |
string |
Google OAuth token | Optional |
reportInterval |
number |
Update throttle interval (ms) | 1000 |
elementSelector |
string |
CSS selector for tracked elements | "[data-et]" |
loggedIn |
boolean |
User login status | Optional |
shouldConnect |
boolean |
Control connection state | true |
| Prop | Type | Description | Default |
|---|---|---|---|
onReport |
function |
Callback for visibility reports | Optional |
updateHash |
boolean |
Update URL hash based on visible elements | false |
# Build server image
cd server
npm run docker:build
# Push to registry
npm run docker:pushversion: "3"
services:
mongodb:
image: mongo:6.0.8
volumes:
- mongodb_data:/data/db
ports:
- 27017:27017
tracker-server:
image: cs124/element-tracker:latest
environment:
- MONGODB=mongodb://mongodb:27017/elementTracker
- GOOGLE_CLIENT_IDS=${GOOGLE_CLIENT_IDS}
- VALID_DOMAINS=${VALID_DOMAINS}
- SECRET=${SECRET}
ports:
- 8080:8000
depends_on:
- mongodb
volumes:
mongodb_data:MIT
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please ensure all checks pass before submitting:
npm run checker