pagewire
v1.1.0
Published
Comprehensive browser monitoring script that captures everything happening in a browser tab and forwards it to a configurable webhook URL
Downloads
199
Maintainers
Readme
PageWire Browser Monitor
A comprehensive browser monitoring library with React hooks and components for seamless integration. Captures everything happening in a browser tab and forwards it to a configurable webhook URL via POST requests.
🚀 React + Vite Ready — Drop-in components, hooks, TypeScript support, and environment-based configuration.
Features
🎯 14 Monitoring Categories
- Console — Intercept all console methods (log, warn, error, info, debug, trace) while preserving original output
- Network — Monitor XMLHttpRequest and fetch API calls with method, URL, status, timing, and response data
- Errors — Capture JavaScript errors, unhandled promise rejections, syntax errors, and resource loading failures
- Performance — Page load timing, resource timing, Core Web Vitals (LCP, FID, CLS), Long Tasks via PerformanceObserver
- DOM Mutations — Summarized element additions, removals, and attribute changes via MutationObserver
- User Interactions — Clicks, scroll events, form inputs, keyboard shortcuts with target element information
- Navigation — URL changes, hash changes, pushState/replaceState interception for SPA routing
- WebSocket — Complete WebSocket lifecycle monitoring (connect, message, close, error events)
- Storage — localStorage and sessionStorage change detection
- Visibility — Tab focus/blur, page visibility changes, beforeunload events
- CSP Violations — SecurityPolicyViolationEvent monitoring
- Deprecation/Intervention Warnings — ReportingObserver integration
- Memory — Periodic performance.memory snapshots (Chrome only)
- Cookie Changes — Via cookieStore API with polling fallback
⚙️ Technical Features
- React Integration — Hooks, providers, and components for modern React apps
- Vite Optimized — Environment variables, SSR detection, development mode support
- TypeScript Ready — Full type definitions included
- Single IIFE — Self-contained, no external dependencies
- Function-based initialization — Configure via
initPageWire(config)function - Event batching — Flushes events every 5 seconds (configurable)
- Smart delivery — Uses
sendBeaconfor reliable delivery on page unload - Unique session tracking — Generated session ID per page load
- Performance optimized — Throttling/debouncing for noisy events
- Error resilient — Comprehensive try/catch blocks prevent page breakage
- Category toggles — Easy enable/disable for each monitoring type
- Memory efficient — Capped buffer size with circular reference handling
- Global kill switch —
stopBrowserMonitoring()function for cleanup
Installation
For React Projects
npm install pagewire
# React 16.8+ required for hooksFor Vanilla JavaScript
npm install pagewireCDN
<script src="https://unpkg.com/pagewire/browser-monitor.js"></script>Download
Download browser-monitor.js from the GitHub repository.
Quick Start
⚛️ React + Vite (Recommended)
// 1. Install
npm install pagewire
// 2. Add to your main App component
import { PageWireProvider } from 'pagewire/react';
function App() {
return (
<PageWireProvider
config={{
webhookUrl: import.meta.env.VITE_PAGEWIRE_WEBHOOK_URL,
categories: { errors: true, performance: true }
}}
>
<MyApplication />
</PageWireProvider>
);
}
// 3. Add to your .env file
VITE_PAGEWIRE_WEBHOOK_URL=https://your-webhook.example.com/eventsBrowser Usage
Option 1: Direct Script Include
<script src="https://unpkg.com/pagewire/browser-monitor.js"></script>
<script>
initPageWire({
webhookUrl: 'https://your-webhook.example.com/events'
});
</script>Option 2: React Integration
import { PageWireProvider } from 'pagewire/react';
function App() {
return (
<PageWireProvider
config={{
webhookUrl: 'https://your-webhook.example.com/events'
}}
>
<MyApplication />
</PageWireProvider>
);
}Option 3: npm + Bundler (Webpack, Vite, etc.)
import { getScriptWithConfig } from 'pagewire';
// Get the script with configuration
const script = getScriptWithConfig('https://your-webhook.example.com/events');
// Inject into page (method varies by framework)
const scriptEl = document.createElement('script');
scriptEl.textContent = script;
document.head.appendChild(scriptEl);Node.js/Server Usage
Express.js Middleware
const { expressMiddleware } = require('pagewire');
app.use(expressMiddleware('https://your-webhook.example.com/events', {
categories: { performance: false, memory: false }
}));Manual Script Generation
const pagewire = require('pagewire');
// Get raw script
const script = pagewire.getScript();
// Get script with config
const configuredScript = pagewire.getScriptWithConfig('https://webhook.com/events');
// Get complete script tag
const scriptTag = pagewire.getScriptTag('https://webhook.com/events', {
flushInterval: 10000
});Configuration Examples
// Basic configuration
initPageWire({
webhookUrl: 'https://your-webhook.example.com/events'
});
// Advanced configuration
initPageWire({
webhookUrl: 'https://your-webhook.example.com/events',
flushInterval: 10000, // Flush every 10 seconds
categories: {
console: true,
network: true,
errors: true,
performance: false, // Disable performance monitoring
userInteractions: true
},
throttle: {
scroll: 500, // Throttle scroll events to every 500ms
memoryCheck: 60000 // Check memory every minute
}
});3. Required Configuration
⚠️ Important: You must provide a webhookUrl or the script will throw an error:
// This will throw an error
initPageWire({}); // Error: webhookUrl is required
// This works
initPageWire({
webhookUrl: 'https://your-webhook.com/events'
});If you don't initialize within 3 seconds, you'll see an error message:
PageWire: Not initialized. Call initPageWire({ webhookUrl: "https://your-webhook.com/events" }) to start monitoring.4. Stop Monitoring
// Call this function to stop all monitoring and clean up
stopBrowserMonitoring();Configuration Options
Pass any of these options to initPageWire(config):
initPageWire({
webhookUrl: 'https://your-webhook.example.com/events', // Required
flushInterval: 5000, // Flush events every 5 seconds
maxBufferSize: 1000, // Maximum events before force flush
// Enable/disable categories
categories: {
console: true,
network: true,
errors: true,
performance: true,
domMutations: true,
userInteractions: true,
navigation: true,
webSocket: true,
storage: true,
visibility: true,
cspViolations: true,
deprecationWarnings: true,
memory: true,
cookieChanges: true
},
// Throttling/debouncing settings
throttle: {
scroll: 250, // Scroll events every 250ms
mousemove: 100, // Mouse events every 100ms
domMutations: 500, // DOM mutation summaries every 500ms
memoryCheck: 30000 // Memory snapshots every 30 seconds
}
});Partial Configuration
You only need to specify the options you want to override:
// Minimal configuration - just set webhook URL
initPageWire({
webhookUrl: 'https://api.mysite.com/monitor'
});
// Disable some categories
initPageWire({
webhookUrl: 'https://api.mysite.com/monitor',
categories: {
performance: false, // Disable performance monitoring
memory: false, // Disable memory monitoring
domMutations: false // Disable DOM mutation tracking
}
});
// Custom throttling
initPageWire({
webhookUrl: 'https://api.mysite.com/monitor',
throttle: {
scroll: 1000, // Less frequent scroll events
memoryCheck: 60000 // Check memory every minute
}
});Event Data Structure
Each event sent to your webhook follows this structure:
{
"timestamp": 1640995200000,
"sessionId": "session_1234567890_abc123def",
"category": "console",
"type": "log",
"data": {
"arguments": ["Hello world", "Debug info"],
"stack": "Error\n at Object.log..."
},
"url": "https://example.com/page",
"userAgent": "Mozilla/5.0..."
}Example Event Types
Console Events
{
"category": "console",
"type": "error",
"data": {
"arguments": ["Error message", errorObject],
"stack": "Error stack trace"
}
}Network Events
{
"category": "network",
"type": "fetch_complete",
"data": {
"method": "POST",
"url": "https://api.example.com/data",
"status": 200,
"duration": 145.2,
"responseSize": 1024
}
}User Interaction Events
{
"category": "userInteractions",
"type": "click",
"data": {
"tagName": "BUTTON",
"id": "submit-btn",
"className": "btn btn-primary",
"x": 150,
"y": 200
}
}Performance Events
{
"category": "performance",
"type": "lcp",
"data": {
"value": 1250.5,
"element": "IMG"
}
}Webhook Integration
Your webhook endpoint should accept POST requests with JSON payloads containing arrays of events:
// Example Express.js webhook handler
app.post('/events', (req, res) => {
const events = req.body; // Array of event objects
events.forEach(event => {
console.log(`[${event.category}] ${event.type}:`, event.data);
// Process, store, or forward the event data
});
res.status(200).send('OK');
});Browser Compatibility
- Modern browsers — Full feature support (Chrome 60+, Firefox 55+, Safari 12+)
- Legacy browsers — Graceful degradation with basic monitoring
- Mobile browsers — Full support on iOS Safari and Chrome Mobile
Security Considerations
- No sensitive data capture — Passwords and secure fields are excluded
- Configurable categories — Disable monitoring types as needed
- Safe serialization — Handles circular references and large objects
- Error isolation — Monitoring failures won't break your application
Use Cases
For React Applications
- ⚛️ Component Error Tracking — Monitor React component errors and lifecycle issues
- 🎯 User Journey Analysis — Track navigation patterns in SPAs
- 🔥 Development Debugging — Real-time error monitoring during development
- 📊 Performance Monitoring — React re-render tracking and Core Web Vitals
- 🧪 A/B Testing — Monitor user interactions across different React variants
- 🛡️ Production Monitoring — Environment-specific error tracking
General Use Cases
- Debugging — Monitor user actions leading to errors
- Performance analysis — Track real user metrics and Core Web Vitals
- User behavior analytics — Understand how users interact with your site
- Error tracking — Comprehensive error monitoring and reporting
- Security monitoring — CSP violations and suspicious activity detection
- A/B testing — Monitor user interactions across different variants
React Integration
React Components and Hooks
PageWire provides React-specific components and hooks for seamless integration with React applications, especially those using Vite.
usePageWire Hook
import { usePageWire } from 'pagewire/react';
function MyComponent() {
const { isInitialized, error, restart, stop } = usePageWire({
webhookUrl: 'https://your-webhook.example.com/events',
categories: {
console: true,
network: true,
errors: true
}
});
if (error) {
return <div>Error: {error}</div>;
}
return (
<div>
<p>Status: {isInitialized ? 'Monitoring' : 'Loading...'}</p>
<button onClick={restart}>Restart</button>
<button onClick={stop}>Stop</button>
</div>
);
}PageWireProvider Component
import { PageWireProvider, usePageWireContext } from 'pagewire/react';
function App() {
return (
<PageWireProvider
config={{
webhookUrl: 'https://your-webhook.example.com/events',
categories: { errors: true, performance: true }
}}
onError={(error) => console.error('PageWire error:', error)}
onInitialized={() => console.log('PageWire ready')}
>
<MyApp />
</PageWireProvider>
);
}
function MyApp() {
const { isInitialized, config } = usePageWireContext();
return <div>App content - Monitoring: {isInitialized}</div>;
}Environment-based Configuration (Vite)
import { PageWireMonitor } from 'pagewire/react';
function App() {
return (
<PageWireMonitor
enabled={import.meta.env.PROD} // Only in production
config={{
webhookUrl: import.meta.env.VITE_PAGEWIRE_WEBHOOK_URL,
categories: {
console: import.meta.env.DEV, // Console logs only in dev
errors: true,
performance: true,
userInteractions: import.meta.env.PROD,
network: true
},
flushInterval: import.meta.env.DEV ? 2000 : 5000 // More frequent in dev
}}
>
<MyApplication />
</PageWireMonitor>
);
}Vite Environment Variables
Create these files in your project root:
.env.development
VITE_PAGEWIRE_WEBHOOK_URL=http://localhost:3001/dev-events.env.production
VITE_PAGEWIRE_WEBHOOK_URL=https://api.yourapp.com/analytics/events.env.local (git-ignored, for local overrides)
VITE_PAGEWIRE_WEBHOOK_URL=https://your-dev-webhook.ngrok.io/eventsTypeScript Support
import { PageWireConfig } from 'pagewire/react';
const config: PageWireConfig = {
webhookUrl: 'https://your-webhook.example.com/events',
categories: {
console: true,
network: true,
errors: true
}
};React Integration Features
- 🔄 SSR Safe — Automatically detects server-side rendering
- 🧹 Automatic Cleanup — Handles component unmounting
- 🛡️ Error Boundaries — Graceful error handling
- 📡 Context API — Share configuration across components
- 🌍 Environment Support — Vite environment variables, development vs production
- 📝 TypeScript — Full type definitions included
- ⚡ Vite Optimized — Works seamlessly with Vite's dev server and build process
- 🔥 Hot Reload Compatible — Properly handles Vite's hot module replacement
API Reference
Node.js/CommonJS
const pagewire = require('pagewire');getScript(): string
Returns the raw browser monitoring script as a string.
getScriptWithConfig(webhookUrl, config?): string
Returns the script with pre-configured initialization.
webhookUrl(string, required): Your webhook URLconfig(object, optional): Additional configuration options
getScriptTag(webhookUrl, config?): string
Returns a complete <script> tag with the monitoring code.
expressMiddleware(webhookUrl, config?): function
Express.js middleware that automatically injects the script into HTML responses.
ES Modules
import { getScript, getScriptWithConfig, getScriptTag, expressMiddleware } from 'pagewire';React Modules
import {
usePageWire,
PageWireProvider,
usePageWireContext,
withPageWire,
PageWireMonitor
} from 'pagewire/react';TypeScript
Full TypeScript definitions are included. The main interfaces:
interface PageWireConfig {
webhookUrl: string;
flushInterval?: number;
maxBufferSize?: number;
categories?: { ... };
throttle?: { ... };
}
declare global {
interface Window {
initPageWire(config: PageWireConfig): string;
stopBrowserMonitoring(): void;
}
}Development
The script is production-ready but you can customize it by:
- Forking the repository and modifying
browser-monitor.js - Adding custom event types in each monitoring function
- Implementing custom throttling strategies
- Extending the data capture for specific categories
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
MIT License - Feel free to use, modify, and distribute.
