blinker-sdk
v1.0.1
Published
Universal JavaScript SDK for error tracking and event capture - works with any framework
Maintainers
Readme
Blinker SDK
Universal JavaScript SDK for error tracking and event capture. Works with any framework - React, Vue, Angular, Next.js, or Vanilla JavaScript.
Features
- 🚀 Zero dependencies - Lightweight and fast
- 🌐 Universal - Works in any JavaScript environment
- 🔄 Automatic error capture - Catches global errors and unhandled rejections
- 🧠 Smart filtering - Ignores common non-bugs (401, 403, ResizeObserver) by default
- 📊 Custom events - Track any event you need
- 📦 Multiple formats - ESM, CommonJS, and UMD (CDN)
- 🔒 Type-safe - Full TypeScript support
Installation
npm / yarn / pnpm
npm install blinker-sdk
# or
yarn add blinker-sdk
# or
pnpm add blinker-sdkCDN
<script src="https://unpkg.com/blinker-sdk/dist/blinker.min.js"></script>
<script>
const { blinker } = BlinkerSDK;
blinker.init({ token: 'your-token' });
</script>Quick Start
import { blinker } from 'blinker-sdk';
// Initialize the SDK - just pass your token!
blinker.init({ token: 'your-blinker-token' });
// That's it! Errors are now automatically captured.
// ✅ Ignores 401/403 errors by default
// ✅ Filters out common browser noise (ResizeObserver, Script error)Usage
Initialization
import { blinker } from 'blinker-sdk';
// Minimal setup - just the token!
blinker.init({ token: 'your-blinker-token' });
// Or with custom options
blinker.init({
token: 'your-blinker-token', // Required: Your API token
captureErrors: true, // Optional: Auto-capture errors (default: true)
captureRejections: true, // Optional: Auto-capture promise rejections (default: true)
debug: false // Optional: Enable debug logging (default: false)
});Error Filters (Smart Defaults)
The SDK comes with intelligent default filters that ignore common non-bug errors. This prevents your error tracking from being cluttered with expected behaviors like authentication failures.
Default Behavior
By default, the SDK ignores:
401and403HTTP errors (authentication/authorization - usually expected behavior)ResizeObserver looperrors (benign browser behavior)Script error(cross-origin errors with no useful info)
// Minimal initialization - all defaults applied automatically!
blinker.init({ token: 'your-token' });
// ✅ Automatically ignores: 401, 403, ResizeObserver loop, Script errorCapture Everything
If you want to capture ALL errors including auth failures:
blinker.init({
token: 'your-token',
filters: { captureAll: true }
});Custom HTTP Code Filters
Customize which HTTP codes to ignore:
// Only ignore 401 (capture 403)
blinker.init({
token: 'your-token',
filters: { ignoreHttpCodes: [401] }
});
// Ignore more codes
blinker.init({
token: 'your-token',
filters: { ignoreHttpCodes: [401, 403, 404, 429] }
});
// Capture ALL HTTP errors (empty array)
blinker.init({
token: 'your-token',
filters: { ignoreHttpCodes: [] }
});Ignore Specific Error Types
Filter out specific JavaScript error types:
blinker.init({
token: 'your-token',
filters: { ignoreErrorTypes: ['TypeError', 'SyntaxError'] }
});Ignore Message Patterns
Filter errors by message content (case-insensitive substring matching):
blinker.init({
token: 'your-token',
filters: {
ignoreMessagePatterns: [
'ResizeObserver loop', // Default
'Script error', // Default
'ChunkLoadError', // Webpack chunk loading
'Loading chunk', // Next.js chunk loading
'Network request failed', // Offline users
'AbortError' // Cancelled requests
]
}
});Full Filter Configuration
All filter options together:
blinker.init({
token: 'your-token',
filters: {
ignoreHttpCodes: [401, 403, 404],
ignoreErrorTypes: ['AbortError'],
ignoreMessagePatterns: ['ResizeObserver loop', 'Script error', 'ChunkLoadError'],
captureAll: false
}
});Check Current Filters
// Get the current filter configuration
const filters = blinker.getFilters();
console.log(filters);
// { ignoreHttpCodes: [401, 403], ignoreErrorTypes: [], ... }Track Custom Events
// Basic event
blinker.track('click', 'Button clicked');
// Event with payload
blinker.track('purchase', 'User made a purchase', {
productId: '12345',
amount: 99.99,
currency: 'USD'
});
// Page view
blinker.trackPageView();
// Page view with custom name
blinker.trackPageView('Home Page', { section: 'hero' });Manual Error Capture
try {
// Your code
} catch (error) {
blinker.captureError(error, { context: 'checkout' });
}
// Or with a string
blinker.captureError('Something went wrong', { userId: '123' });Check SDK Status
// Check if initialized
if (blinker.isInitialized()) {
// SDK is ready
}
// Get current config (without sensitive data)
const config = blinker.getConfig();Cleanup
// Remove error handlers and reset SDK
blinker.destroy();Framework Examples
React
// app.jsx or index.jsx
import { blinker } from 'blinker-sdk';
blinker.init({ token: process.env.REACT_APP_BLINKER_TOKEN });
function App() {
const handleClick = () => {
blinker.track('click', 'CTA button clicked', { page: 'home' });
};
return <button onClick={handleClick}>Click me</button>;
}Next.js
// app/layout.tsx or pages/_app.tsx
'use client';
import { useEffect } from 'react';
import { blinker } from 'blinker-sdk';
export default function RootLayout({ children }) {
useEffect(() => {
blinker.init({ token: process.env.NEXT_PUBLIC_BLINKER_TOKEN });
}, []);
return (
<html>
<body>{children}</body>
</html>
);
}Vue.js
// main.js
import { createApp } from 'vue';
import { blinker } from 'blinker-sdk';
import App from './App.vue';
blinker.init({ token: import.meta.env.VITE_BLINKER_TOKEN });
createApp(App).mount('#app');Angular
// app.module.ts
import { blinker } from 'blinker-sdk';
blinker.init({ token: environment.blinkerToken });
@NgModule({
// ...
})
export class AppModule {}Vanilla JavaScript
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/blinker-sdk/dist/blinker.min.js"></script>
</head>
<body>
<button id="myButton">Click me</button>
<script>
const { blinker } = BlinkerSDK;
blinker.init({ token: 'your-token' });
document.getElementById('myButton').addEventListener('click', () => {
blinker.track('click', 'Button clicked');
});
</script>
</body>
</html>API Reference
blinker.init(config)
Initialize the SDK with configuration options.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| token | string | required | Your Blinker API token |
| captureErrors | boolean | true | Auto-capture window errors |
| captureRejections | boolean | true | Auto-capture unhandled rejections |
| debug | boolean | false | Enable debug logging |
| filters | FilterSettings | see below | Error filter configuration |
FilterSettings
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| ignoreHttpCodes | number[] | [401, 403] | HTTP status codes to ignore |
| ignoreErrorTypes | string[] | [] | JS error types to ignore (e.g., 'TypeError') |
| ignoreMessagePatterns | string[] | ['ResizeObserver loop', 'Script error'] | Message patterns to ignore |
| captureAll | boolean | false | When true, disables all filters |
blinker.track(type, message, payload?)
Track a custom event.
| Parameter | Type | Description |
|-----------|------|-------------|
| type | string | Event type (e.g., 'click', 'purchase') |
| message | string | Event description |
| payload | object | Optional additional data |
Returns: Promise<{ success: boolean, error?: string }>
blinker.captureError(error, payload?)
Manually capture an error.
| Parameter | Type | Description |
|-----------|------|-------------|
| error | Error \| string | Error object or message |
| payload | object | Optional additional data |
blinker.trackPageView(pageName?, payload?)
Track a page view.
| Parameter | Type | Description |
|-----------|------|-------------|
| pageName | string | Optional page name (defaults to URL path) |
| payload | object | Optional additional data |
blinker.isInitialized()
Check if SDK is initialized. Returns boolean.
blinker.getConfig()
Get current configuration (without token). Returns config object or null.
blinker.getFilters()
Get current filter settings. Returns FilterSettings object.
const filters = blinker.getFilters();
// { ignoreHttpCodes: [401, 403], ignoreErrorTypes: [], ignoreMessagePatterns: [...], captureAll: false }blinker.destroy()
Remove error handlers and reset SDK state.
Event Payload
Events sent to the API have the following structure:
{
"type": "error",
"message": "Error message",
"payload": {
"custom": "data"
},
"timestamp": "2024-01-15T12:00:00.000Z",
"url": "https://example.com/page",
"userAgent": "Mozilla/5.0..."
}TypeScript
The SDK is written in TypeScript and includes type definitions.
import { blinker, BlinkerConfig, FilterSettings } from 'blinker-sdk';
// Minimal config - just the token!
blinker.init({ token: 'your-token' });
// Or with full typed config
const config: BlinkerConfig = {
token: 'your-token',
filters: {
ignoreHttpCodes: [401, 403, 404],
captureAll: false
}
};
blinker.init(config);
// Get typed filters
const filters: FilterSettings = blinker.getFilters();Multiple Instances
If you need multiple SDK instances (e.g., different tokens for different app sections):
import { Blinker } from 'blinker-sdk';
const frontendErrors = new Blinker();
const backendErrors = new Blinker();
frontendErrors.init({ token: 'frontend-token' });
backendErrors.init({ token: 'backend-token' });Browser Support
- Chrome 63+
- Firefox 67+
- Safari 12+
- Edge 79+
The SDK uses modern JavaScript features (ES2018) including async/await and fetch.
License
MIT
