@interfere/next
v0.0.14
Published
Build apps that never break.
Downloads
47
Maintainers
Readme
@interfere/next
Official Next.js SDK for Interfere error monitoring and analytics.
Installation
npm install @interfere/next
# or
yarn add @interfere/next
# or
pnpm add @interfere/nextQuick Start
1. Initialize the SDK
Create a file to initialize Interfere (e.g., lib/interfere.ts):
import { init } from '@interfere/next';
export const interfere = init({
project: process.env.NEXT_PUBLIC_INTERFERE_PROJECT_ID!,
options: {
env: process.env.NODE_ENV as 'development' | 'preview' | 'production',
debug: process.env.NODE_ENV === 'development',
},
});2. Add Error Boundary (App Directory)
In your root layout (app/layout.tsx):
import { InterfereProvider, InterfereErrorBoundary } from '@interfere/next';
import { interfere } from '@/lib/interfere';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<InterfereProvider>
<InterfereErrorBoundary>
{children}
</InterfereErrorBoundary>
</InterfereProvider>
</body>
</html>
);
}3. Add Error Handler (App Directory)
Create app/error.tsx:
'use client';
import { useEffect } from 'react';
import { captureErrorBoundaryError } from '@interfere/next';
export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
useEffect(() => {
captureErrorBoundaryError(error, {
componentStack: error.stack || '',
});
}, [error]);
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}4. Add Global Error Handler
Create app/global-error.tsx:
'use client';
import { createInterfereErrorHandler } from '@interfere/next';
const errorHandler = createInterfereErrorHandler();
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
errorHandler(error, { digest: error.digest });
return (
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
);
}API Routes
Automatic Error Capture
Wrap your API route handlers:
// app/api/users/route.ts
import { withInterfereApiRoute } from '@interfere/next';
export const GET = withInterfereApiRoute(async (request) => {
// Your API logic here
const users = await fetchUsers();
return Response.json(users);
});Manual Error Capture
// app/api/webhook/route.ts
import { captureServerError } from '@interfere/next';
export async function POST(request: Request) {
try {
const body = await request.json();
// Process webhook
} catch (error) {
captureServerError(error, request, {
pathname: '/api/webhook',
type: 'webhook_error',
});
return Response.json({ error: 'Webhook failed' }, { status: 500 });
}
}Middleware
Wrap your middleware to capture errors:
// middleware.ts
import { withInterfereMiddleware } from '@interfere/next';
import { NextResponse } from 'next/server';
export default withInterfereMiddleware(async (request) => {
// Your middleware logic
return NextResponse.next();
});
export const config = {
matcher: '/api/:path*',
};Server Components
Wrap async server components:
// app/dashboard/page.tsx
import { withInterfereServerComponent } from '@interfere/next';
async function DashboardPage() {
const data = await fetchDashboardData();
return <Dashboard data={data} />;
}
export default withInterfereServerComponent(DashboardPage, 'DashboardPage');Custom Event Capture
Capture custom events and errors:
import { capture, captureServerError } from '@interfere/next';
// Capture custom events
capture('custom', {
action: 'user_signup',
userId: user.id,
plan: 'premium',
});
// Capture handled errors
try {
await riskyOperation();
} catch (error) {
captureServerError(error, undefined, {
operation: 'risky_operation',
context: { userId: user.id },
});
}React Hook
Use the useInterfere hook in client components:
'use client';
import { useInterfere } from '@interfere/next';
export function Button() {
const { capture } = useInterfere();
const handleClick = () => {
capture('ui_event', {
action: 'button_click',
label: 'cta_button',
});
};
return <button onClick={handleClick}>Click me</button>;
}Configuration Options
init({
project: 'if_proj_xxx', // Your project ID
options: {
env: 'production', // 'development' | 'preview' | 'production'
flushInterval: 5000, // Flush interval in ms (client-side only)
debug: false, // Enable debug logging
sessionId: 'custom-session-id', // Optional custom session ID
},
});Event Types
The SDK automatically captures these event types:
error- Client-side errors (unhandled errors, promise rejections)server_error- Server-side errors in API routes and server componentsedge_error- Edge runtime errors in middlewareserver_req- Server request events (API routes)edge_req- Edge request events (middleware)ui_event- User interface eventscustom- Custom application eventsnetwork- Network request events (coming soon)rage_click- rage clicks
Best Practices
Initialize Early: Initialize Interfere as early as possible in your application lifecycle.
Use Error Boundaries: Always wrap your app with
InterfereErrorBoundaryto catch React errors.Wrap Async Functions: Use
withErrorCaptureor specific wrappers for automatic error tracking.Add Context: Include relevant context when capturing errors manually:
captureServerError(error, request, { userId: session.userId, action: 'update_profile', metadata: { ... }, });Environment Variables: Store your project ID in environment variables:
NEXT_PUBLIC_INTERFERE_PROJECT_ID=if_proj_xxx
TypeScript
The SDK is fully typed. Import types as needed:
import type {
Config,
InitConfig,
EventType,
Envelope,
} from '@interfere/next';License
MIT
