Skip to content

Framework Guides

This page provides integration examples for different JavaScript frameworks and environments.

For vanilla JavaScript projects, initialize the widget in your main entry file or after the DOM is ready.

import { createOopsWidget, LogLevel } from '@upreport/oops-widget';
import { FetchInterceptor } from '@upreport/oops-widget/fetchInterceptor';
import { XHRInterceptor } from '@upreport/oops-widget/xhrInterceptor';
import { StatusAlert } from '@upreport/oops-widget/statusAlert';
import { createAutoDetectI18nProvider } from '@upreport/oops-widget/i18n';
const interceptorConfig = {
timeoutMs: 20000,
showSlowRequestAlerts: true,
showErrorAlerts: true,
monitoredServicePatterns: ['/api/*'],
monitoredServiceOptions: {
requireExplicitPatterns: true,
includeCurrentOrigin: true,
},
};
const widget = createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
placement: 'bottom-right',
interceptors: [
new FetchInterceptor(interceptorConfig),
new XHRInterceptor(interceptorConfig),
],
mobile: {
enabled: true,
placement: 'top',
},
logLevel: LogLevel.DEBUG,
});
widget
.start()
.then(() => console.log('Widget started'))
.catch((error) => console.error('Error starting widget:', error));

If you need to wait for the DOM:

document.addEventListener('DOMContentLoaded', () => {
const widget = createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
});
widget.start();
});

For Vue applications, initialize the widget in your root component or main entry file. The widget works independently of Vue’s reactivity system.

Initialize in your App.vue or main.ts:

<script lang="ts" setup>
import { createOopsWidget, LogLevel } from '@upreport/oops-widget';
import { FetchInterceptor } from '@upreport/oops-widget/fetchInterceptor';
import { XHRInterceptor } from '@upreport/oops-widget/xhrInterceptor';
import { StatusAlert } from '@upreport/oops-widget/statusAlert';
import { createAutoDetectI18nProvider } from '@upreport/oops-widget/i18n';
const interceptorConfig = {
timeoutMs: 20000,
showSlowRequestAlerts: true,
monitoredServicePatterns: ['/api/*'],
monitoredServiceOptions: {
requireExplicitPatterns: true,
includeCurrentOrigin: true,
},
};
createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
placement: 'top-right',
interceptors: [
new FetchInterceptor(interceptorConfig),
new XHRInterceptor(interceptorConfig),
],
mobile: {
enabled: true,
placement: 'bottom',
},
logLevel: LogLevel.DEBUG,
});
</script>
<template>
<router-view />
</template>
main.ts
import { createApp } from 'vue';
import { createOopsWidget } from '@upreport/oops-widget';
import { StatusAlert } from '@upreport/oops-widget/statusAlert';
import { createAutoDetectI18nProvider } from '@upreport/oops-widget/i18n';
import App from './App.vue';
// Initialize widget before mounting
createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
}).start();
createApp(App).mount('#app');

For React applications, initialize the widget using a useEffect hook to ensure proper cleanup when the component unmounts.

import { useEffect } from 'react';
import { createOopsWidget, LogLevel } from '@upreport/oops-widget';
import { FetchInterceptor } from '@upreport/oops-widget/fetchInterceptor';
import { XHRInterceptor } from '@upreport/oops-widget/xhrInterceptor';
import { StatusAlert } from '@upreport/oops-widget/statusAlert';
import { createAutoDetectI18nProvider } from '@upreport/oops-widget/i18n';
function App() {
useEffect(() => {
const interceptorConfig = {
timeoutMs: 20000,
showSlowRequestAlerts: true,
showErrorAlerts: true,
monitoredServicePatterns: ['/api/*'],
monitoredServiceOptions: {
requireExplicitPatterns: true,
includeCurrentOrigin: true,
},
};
const widget = createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
placement: 'bottom-right',
interceptors: [
new FetchInterceptor(interceptorConfig),
new XHRInterceptor(interceptorConfig),
],
mobile: {
enabled: true,
placement: 'top',
},
logLevel: LogLevel.DEBUG,
});
widget.start();
// Cleanup on unmount
return () => {
widget.destroy();
};
}, []);
return <div>{/* Your app content */}</div>;
}
export default App;

Create a reusable hook for cleaner code:

useOopsWidget.ts
import { useEffect, useRef } from 'react';
import {
createOopsWidget,
OopsWidgetConfig,
OopsWidgetInstance,
} from '@upreport/oops-widget';
export function useOopsWidget(config: OopsWidgetConfig) {
const widgetRef = useRef<OopsWidgetInstance | null>(null);
useEffect(() => {
const widget = createOopsWidget(config);
widgetRef.current = widget;
widget.start();
return () => {
widget.destroy();
};
}, []);
return widgetRef;
}

Usage:

App.tsx
import { useOopsWidget } from './useOopsWidget';
import { StatusAlert } from '@upreport/oops-widget/statusAlert';
import { createAutoDetectI18nProvider } from '@upreport/oops-widget/i18n';
function App() {
useOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
});
return <div>{/* Your app content */}</div>;
}

For Next.js applications, ensure the widget only runs on the client side.

'use client';
import { useEffect } from 'react';
import { createOopsWidget } from '@upreport/oops-widget';
import { StatusAlert } from '@upreport/oops-widget/statusAlert';
import { createAutoDetectI18nProvider } from '@upreport/oops-widget/i18n';
export function OopsWidgetProvider({
children,
}: {
children: React.ReactNode;
}) {
useEffect(() => {
const widget = createOopsWidget({
statusUrl: 'YOUR_STATUS_URL_FROM_CONSOLE',
alertComponent: StatusAlert,
i18nProvider: createAutoDetectI18nProvider(),
});
widget.start();
return () => widget.destroy();
}, []);
return <>{children}</>;
}

Use in your layout:

app/layout.tsx
import { OopsWidgetProvider } from './OopsWidgetProvider';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html>
<body>
<OopsWidgetProvider>{children}</OopsWidgetProvider>
</body>
</html>
);
}