Skip to content

API Reference

This page provides the complete API reference for the Oops Widget, including types and custom component creation.

Creates and returns a widget instance.

function createOopsWidget(config: OopsWidgetConfig): OopsWidgetInstance;
MethodDescription
start(): Promise<void>Performs initial status check and starts monitoring
destroy(): voidStops monitoring and cleans up all resources
const widget = createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
});
// Start the widget
await widget.start();
// Later, when cleaning up
widget.destroy();

Both FetchInterceptor and XHRInterceptor implement the Interceptor interface:

interface Interceptor {
name: string;
setup(): () => void; // Returns cleanup function
}

Monitors all fetch() API calls:

import { FetchInterceptor } from '@upreport/oops-widget/fetchInterceptor';
const interceptor = new FetchInterceptor({
timeoutMs: 20000,
showSlowRequestAlerts: true,
showErrorAlerts: true,
monitoredServicePatterns: ['/api/*'],
});

Monitors all XMLHttpRequest calls:

import { XHRInterceptor } from '@upreport/oops-widget/xhrInterceptor';
const interceptor = new XHRInterceptor({
timeoutMs: 20000,
showSlowRequestAlerts: true,
showErrorAlerts: true,
monitoredServicePatterns: ['/api/*'],
});

Represents the possible system statuses:

enum SystemStatus {
Operational = 'Operational',
DegradedPerformance = 'DegradedPerformance',
PartialOutage = 'PartialOutage',
MajorOutage = 'MajorOutage',
UnderMaintenance = 'UnderMaintenance',
}

Response from the status endpoint:

interface SystemStatusResponse {
status: SystemStatus;
incident?: IncidentInfo;
rawData: Record<string, string>;
}

Logging verbosity levels:

enum LogLevel {
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3,
NONE = 4,
}

Interface for internationalization providers:

interface I18nProvider {
getStatusDetails(status: SystemStatus): Promise<StatusDetails>;
}
interface StatusDetails {
title: string;
message: string;
}

Full configuration interface:

interface OopsWidgetConfig {
statusUrl: string;
alertComponent: CustomElementConstructor;
i18nProvider: I18nProvider;
placement?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
interceptors?: Interceptor[];
mobile?: {
enabled: boolean;
placement?: 'top' | 'bottom';
mediaQuery?: string;
};
logLevel?: LogLevel;
alertClosureBehavior?: Partial<
Record<
SystemStatus,
{
closeDurationMs?: number;
checkIntervalMs?: number;
}
>
>;
displayIncidentDetails?: boolean;
useSandboxedFetch?: boolean;
}

Configuration for request interceptors:

interface InterceptorConfig {
timeoutMs?: number;
showSlowRequestAlerts?: boolean;
showErrorAlerts?: boolean;
monitoredServicePatterns?: string[];
monitoredServiceOptions?: {
requireExplicitPatterns?: boolean;
includeCurrentOrigin?: boolean;
treatRelativeAsInternal?: boolean;
};
}

You can replace the built-in StatusAlert with your own Web Component implementation.

Custom alert components must:

  1. Be implemented as a Web Component (Custom Element)
  2. Handle the required attributes
  3. Dispatch and listen for widget events

Your component should observe these attributes:

AttributeDescription
status-typeCurrent system status (e.g., 'MajorOutage')
titleAlert title text
messageAlert message text
placementPosition on screen
mobile-enabledWhether mobile mode is enabled
mobile-placementMobile-specific placement
progress-durationTimer duration for progress animation
incident-namesJSON string of incident names
incident-statusesJSON string of incident statuses
incident-linksJSON string of incident detail links
display-incident-detailsWhether to show incident details
close-button-labelAccessibility label for close button
EventDirectionDescription
oops-widget-closedAlert → CoreDispatched when user clicks close button
oops-widget-timer-startCore → AlertSent when alert timer starts (includes duration in detail)
oops-widget-timer-cancelCore → AlertSent when timer is cancelled
class MyCustomAlert extends HTMLElement {
private shadow: ShadowRoot;
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
}
static get observedAttributes(): string[] {
return [
'status-type',
'title',
'message',
'placement',
'close-button-label',
];
}
connectedCallback(): void {
this.render();
this.setupEvents();
}
attributeChangedCallback(): void {
this.render();
}
private setupEvents(): void {
// Handle close button click
const closeBtn = this.shadow.querySelector('.close-btn');
if (closeBtn) {
closeBtn.addEventListener('click', () => {
this.dispatchEvent(
new CustomEvent('oops-widget-closed', {
bubbles: true,
composed: true,
})
);
});
}
// Handle timer events
this.addEventListener('oops-widget-timer-start', (e: Event) => {
const { duration } = (e as CustomEvent<{ duration: number }>).detail;
const progress = this.shadow.querySelector('.progress-bar');
if (progress instanceof HTMLElement) {
progress.style.transition = `width ${duration}ms linear`;
progress.style.width = '100%';
}
});
this.addEventListener('oops-widget-timer-cancel', () => {
const progress = this.shadow.querySelector('.progress-bar');
if (progress instanceof HTMLElement) {
progress.style.transition = 'none';
progress.style.width = '0';
}
});
}
private render(): void {
const status = this.getAttribute('status-type') || 'DegradedPerformance';
const title = this.getAttribute('title') || 'Status Alert';
const message = this.getAttribute('message') || '';
const closeLabel = this.getAttribute('close-button-label') || 'Close';
const colors: Record<string, string> = {
MajorOutage: '#f8d7da',
PartialOutage: '#ffebd6',
DegradedPerformance: '#fff3cd',
UnderMaintenance: '#e7f1fc',
Operational: '#d4edda',
};
const bgColor = colors[status] || colors.DegradedPerformance;
this.shadow.innerHTML = `
<style>
.alert {
background: ${bgColor};
padding: 16px;
border-radius: 8px;
position: relative;
overflow: hidden;
font-family: system-ui, sans-serif;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.close-btn {
background: none;
border: none;
cursor: pointer;
font-size: 18px;
padding: 4px 8px;
}
.progress-bar {
position: absolute;
bottom: 0;
left: 0;
height: 3px;
width: 0;
background: rgba(0,0,0,0.2);
}
</style>
<div class="alert">
<div class="header">
<strong>${title}</strong>
<button class="close-btn" aria-label="${closeLabel}">×</button>
</div>
<p>${message}</p>
<div class="progress-bar"></div>
</div>
`;
}
}
// Register the custom element
customElements.define('my-custom-alert', MyCustomAlert);
// Use in widget configuration
const widget = createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: MyCustomAlert,
i18nProvider: createAutoDetectI18nProvider(),
});

All available imports from the package:

// Main exports
import {
createOopsWidget,
LogLevel,
SystemStatus,
} from '@upreport/oops-widget';
// Alert component
import { StatusAlert } from '@upreport/oops-widget/statusAlert';
// Interceptors
import { FetchInterceptor } from '@upreport/oops-widget/fetchInterceptor';
import { XHRInterceptor } from '@upreport/oops-widget/xhrInterceptor';
// i18n providers
import {
createAutoDetectI18nProvider,
createStaticI18nProvider,
} from '@upreport/oops-widget/i18n';
// Types (TypeScript)
import type {
OopsWidgetConfig,
OopsWidgetInstance,
InterceptorConfig,
Interceptor,
I18nProvider,
StatusDetails,
SystemStatusResponse,
} from '@upreport/oops-widget';