jayden7-web-monitor-sdk
v1.0.4
Published
A lightweight web performance monitoring, error tracking and behavior analytics SDK
Downloads
422
Maintainers
Readme
jayden7-web-monitor-sdk
Production-ready frontend monitoring SDK with low overhead and high reliability.
Features
- Performance metrics:
FP/FCP/LCP/CLS/TTI/resource - Error tracking: JS runtime, Promise, resource load, Vue/React
- Network tracking: Fetch/XHR status and duration
- Behavior tracking: route change, page view, click, stay duration
- Reliable transport: memory queue + localStorage fallback +
sendBeacon - Class + plugin architecture, easy to extend and maintain
Installation
npm install jayden7-web-monitor-sdkQuick Start
import { init } from 'jayden7-web-monitor-sdk';
init({
url: 'https://your-server.com/api/report',
projectName: 'my-app',
appId: 'app-001',
userId: 'u-10001',
batchSize: 20,
sampleRate: 1,
flushInterval: 5000,
enable: {
performance: true,
error: true,
behavior: true,
network: true
}
});Early Error Preload Script
Place this script at the top of index.html <head>, before business scripts:
<script>
(function () {
var PRELOAD_QUEUE_KEY = '__webEyePreloadQueue__';
var PRELOAD_STORAGE_KEY = '__webEyePreloadCache__';
var win = window;
win[PRELOAD_QUEUE_KEY] = win[PRELOAD_QUEUE_KEY] || [];
function pushEarly(item) {
try {
win[PRELOAD_QUEUE_KEY].push(item);
var cache = JSON.parse(localStorage.getItem(PRELOAD_STORAGE_KEY) || '[]');
cache.push(item);
if (cache.length > 50) cache = cache.slice(cache.length - 50);
localStorage.setItem(PRELOAD_STORAGE_KEY, JSON.stringify(cache));
} catch (e) {}
}
win.addEventListener('error', function (e) {
var target = e.target;
if (target && target !== win) {
pushEarly({ type: 'error', subType: 'resource-preload', message: 'resource load error', href: target.src || target.href || '', ts: Date.now() });
return;
}
pushEarly({ type: 'error', subType: 'js-preload', message: e.message || '', stack: (e.error && e.error.stack) || '', href: e.filename || '', ts: Date.now() });
}, true);
win.addEventListener('unhandledrejection', function (e) {
var reason = e.reason || {};
pushEarly({ type: 'error', subType: 'promise-preload', message: reason.message || String(reason), stack: reason.stack || '', href: win.location.href, ts: Date.now() });
}, true);
})();
</script>Vue Integration
import { createApp } from 'vue';
import App from './App.vue';
import { install, init } from 'jayden7-web-monitor-sdk';
const app = createApp(App);
install(app, {
url: 'https://your-server.com/api/report',
projectName: 'demo-vue-app',
appId: 'vue-app'
});
init({
url: 'https://your-server.com/api/report',
projectName: 'demo-vue-app',
appId: 'vue-app',
enable: {
performance: true,
error: true,
behavior: true,
network: true
}
});
app.mount('#app');React Integration
import React from 'react';
import { errorBoundary, init } from 'jayden7-web-monitor-sdk';
init({
url: 'https://your-server.com/api/report',
projectName: 'demo-react-app',
appId: 'react-app',
enable: {
performance: true,
error: true,
behavior: true,
network: true
}
});
class MonitorBoundary extends React.Component<React.PropsWithChildren> {
componentDidCatch(error: Error, info: React.ErrorInfo): void {
errorBoundary(error, info);
}
render(): React.ReactNode {
return this.props.children;
}
}
export default MonitorBoundary;CDN Integration
<script src="https://unpkg.com/jayden7-web-monitor-sdk/dist/monitor.js"></script>
<script>
monitor.init({
url: 'https://your-server.com/api/report',
projectName: 'demo-cdn-app',
appId: 'cdn-app',
batchSize: 20,
sampleRate: 1,
enable: {
performance: true,
error: true,
behavior: true,
network: true
}
});
</script>Configuration
| Field | Type | Default | Description |
| --- | --- | --- | --- |
| url | string | '' | Report endpoint (required) |
| projectName | string | '' | Project identifier |
| appId | string | '' | App identifier |
| userId | string | '' | User identifier |
| isImageUpload | boolean | false | Use image transport |
| batchSize | number | 20 | Queue threshold for batch send |
| sampleRate | number | 1 | Event sampling rate (0 ~ 1) |
| flushInterval | number | 5000 | Periodic flush interval |
| maxRetryCount | number | 3 | Retry count when send fails |
| disableCache | boolean | false | Disable localStorage fallback |
| customFields | Record<string, unknown> | {} | Extra custom fields |
| enable.performance | boolean | true | Enable performance plugin |
| enable.error | boolean | true | Enable error plugin |
| enable.behavior | boolean | true | Enable behavior plugin |
| enable.network | boolean | true | Enable network plugin |
Build And Publish
npm install
npm run typecheck
npm run build
npm version patch
npm publish --access publicFull Integration Checklist
- Ensure report endpoint is reachable and CORS-enabled.
- Add preload script in
index.htmlhead before business code. - Initialize SDK as early as possible in app bootstrap.
- Enable required plugins via
enableoptions. - Verify
sendBeacondelivery onpagehideand tab close. - Validate retry and localStorage fallback with offline simulation.
- Confirm Vue/React framework error hooks are connected.
- Keep
sampleRateandbatchSizetuned per traffic level.
Complete HTML Demo
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>webEyeSDK preload demo</title>
<script>
(function () {
var PRELOAD_QUEUE_KEY = '__webEyePreloadQueue__';
var PRELOAD_STORAGE_KEY = '__webEyePreloadCache__';
var win = window;
win[PRELOAD_QUEUE_KEY] = win[PRELOAD_QUEUE_KEY] || [];
function pushEarly(item) {
try {
win[PRELOAD_QUEUE_KEY].push(item);
var cache = JSON.parse(localStorage.getItem(PRELOAD_STORAGE_KEY) || '[]');
cache.push(item);
if (cache.length > 50) cache = cache.slice(cache.length - 50);
localStorage.setItem(PRELOAD_STORAGE_KEY, JSON.stringify(cache));
} catch (e) {}
}
win.addEventListener('error', function (e) {
var target = e.target;
if (target && target !== win) {
pushEarly({
type: 'error',
subType: 'resource-preload',
message: 'resource load error',
href: target.src || target.href || '',
ts: Date.now()
});
return;
}
pushEarly({
type: 'error',
subType: 'js-preload',
message: e.message || '',
stack: (e.error && e.error.stack) || '',
href: e.filename || '',
ts: Date.now()
});
}, true);
win.addEventListener('unhandledrejection', function (e) {
var reason = e.reason || {};
pushEarly({
type: 'error',
subType: 'promise-preload',
message: reason.message || String(reason),
stack: reason.stack || '',
href: win.location.href,
ts: Date.now()
});
}, true);
})();
</script>
</head>
<body>
<h1>webEyeSDK Demo</h1>
<button id="btn">制造错误</button>
<script src="https://unpkg.com/jayden7-web-monitor-sdk/dist/monitor.js"></script>
<script>
monitor.init({
url: 'http://127.0.0.1:8080/api',
projectName: 'demo-app',
appId: 'demo-app-id',
userId: 'u-10001',
sampleRate: 1,
batchSize: 20,
flushInterval: 5000,
enable: {
performance: true,
error: true,
behavior: true,
network: true
}
});
document.getElementById('btn').addEventListener('click', function () {
Promise.reject(new Error('test promise error'));
setTimeout(function () {
throw new Error('test js error');
}, 0);
});
</script>
</body>
</html>License
MIT
