Package Exports
- jayden7-web-monitor-sdk
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