LogRocket
LogRocket: session replay, error tracking, performance monitoring, Redux/Vuex integration, network logging
LogRocket is a frontend monitoring platform centered on session replay. Its core principles are: ## Key Points - **Reproduce every bug visually** — session replay eliminates "works on my machine" by showing exactly what the user saw, clicked, and experienced. - **Correlate errors with user behavior** — stack traces paired with a video-like replay of the session make root-cause analysis immediate. - **Network requests are first-class data** — every XHR/fetch request and response is captured, giving full visibility into API failures without backend instrumentation. - **State management is observable** — Redux, Vuex, and other store mutations are logged alongside the replay timeline so you can see the exact state that triggered a bug. - **Privacy by design** — sensitive fields must be sanitized at the SDK level before data leaves the browser. 1. **Sanitize all sensitive inputs** — enable `inputSanitizer` and use `requestSanitizer` to strip auth headers and PII from network payloads. 2. **Identify users after login** — call `LogRocket.identify()` so sessions are searchable by user and you can measure impact per account. 3. **Connect to your error tracker** — pipe the session URL into Sentry, Bugsnag, or your issue tracker so every error links directly to replay. 4. **Use custom events for funnels** — `LogRocket.track()` events power conversion funnels in the LogRocket dashboard. 5. **Limit recording in non-production** — only initialize in production or explicitly opted-in staging environments. 6. **Strip Redux auth state** — use `stateSanitizer` to remove tokens and credentials from the recorded store snapshots. 7. **Monitor slow network calls** — track requests over a duration threshold to surface API performance issues from the frontend perspective.
skilldb get monitoring-services-skills/logrocketFull skill: 332 linesLogRocket Monitoring Skill
Core Philosophy
LogRocket is a frontend monitoring platform centered on session replay. Its core principles are:
- Reproduce every bug visually — session replay eliminates "works on my machine" by showing exactly what the user saw, clicked, and experienced.
- Correlate errors with user behavior — stack traces paired with a video-like replay of the session make root-cause analysis immediate.
- Network requests are first-class data — every XHR/fetch request and response is captured, giving full visibility into API failures without backend instrumentation.
- State management is observable — Redux, Vuex, and other store mutations are logged alongside the replay timeline so you can see the exact state that triggered a bug.
- Privacy by design — sensitive fields must be sanitized at the SDK level before data leaves the browser.
Setup
React Application Setup
// lib/logrocket.ts
import LogRocket from "logrocket";
import setupLogRocketReact from "logrocket-react";
const LOGROCKET_APP_ID = process.env.NEXT_PUBLIC_LOGROCKET_APP_ID!;
let initialized = false;
export function initLogRocket() {
if (initialized || typeof window === "undefined") return;
initialized = true;
LogRocket.init(LOGROCKET_APP_ID, {
release: process.env.NEXT_PUBLIC_APP_VERSION,
console: {
isEnabled: true,
shouldAggregateConsoleErrors: true,
},
network: {
isEnabled: true,
requestSanitizer(request) {
if (request.headers["Authorization"]) {
request.headers["Authorization"] = "[REDACTED]";
}
if (request.url.includes("/api/auth")) {
request.body = undefined;
}
return request;
},
responseSanitizer(response) {
return response;
},
},
dom: {
inputSanitizer: true,
textSanitizer: false,
},
});
setupLogRocketReact(LogRocket);
}
export function identifyUser(user: {
id: string;
name: string;
email: string;
plan: string;
}) {
LogRocket.identify(user.id, {
name: user.name,
email: user.email,
plan: user.plan,
});
}
export { LogRocket };
App-Level Initialization
// app/providers.tsx
"use client";
import { useEffect } from "react";
import { initLogRocket } from "@/lib/logrocket";
export function MonitoringProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
if (process.env.NODE_ENV === "production") {
initLogRocket();
}
}, []);
return <>{children}</>;
}
Redux Integration
// store/index.ts
import { configureStore } from "@reduxjs/toolkit";
import LogRocket from "logrocket";
import createLogRocketMiddleware from "logrocket-redux";
const logRocketMiddleware = createLogRocketMiddleware(LogRocket, {
stateSanitizer(state) {
return {
...state,
auth: undefined, // Strip auth state from session data
};
},
actionSanitizer(action) {
if (action.type === "auth/setToken") {
return { ...action, payload: "[REDACTED]" };
}
return action;
},
});
export const store = configureStore({
reducer: {
// your reducers
},
middleware: (getDefault) => getDefault().concat(logRocketMiddleware),
});
Key Techniques
Error Boundary with Session URL
// components/LogRocketErrorBoundary.tsx
import { Component, type ErrorInfo, type ReactNode } from "react";
import LogRocket from "logrocket";
interface Props {
fallback: (props: { sessionUrl: string | null; retry: () => void }) => ReactNode;
children: ReactNode;
}
interface State {
hasError: boolean;
sessionUrl: string | null;
}
export class LogRocketErrorBoundary extends Component<Props, State> {
state: State = { hasError: false, sessionUrl: null };
static getDerivedStateFromError(): Partial<State> {
return { hasError: true };
}
componentDidCatch(error: Error, info: ErrorInfo) {
LogRocket.captureException(error, {
tags: { componentStack: "true" },
extra: { componentStack: info.componentStack },
});
LogRocket.getSessionURL((sessionURL) => {
this.setState({ sessionUrl: sessionURL });
// Send session URL to your issue tracker
reportToIssueTracker(error, sessionURL);
});
}
retry = () => this.setState({ hasError: false, sessionUrl: null });
render() {
if (this.state.hasError) {
return this.props.fallback({
sessionUrl: this.state.sessionUrl,
retry: this.retry,
});
}
return this.props.children;
}
}
async function reportToIssueTracker(error: Error, sessionUrl: string) {
await fetch("/api/report-error", {
method: "POST",
body: JSON.stringify({
message: error.message,
stack: error.stack,
sessionUrl,
}),
});
}
Custom Event Tracking
// lib/logrocket-events.ts
import LogRocket from "logrocket";
export function trackFeatureUsage(feature: string, metadata?: Record<string, string | number>) {
LogRocket.track(feature, metadata);
}
export function trackConversion(event: string, revenue?: number) {
LogRocket.track(event, {
revenue: revenue ?? 0,
currency: "USD",
timestamp: Date.now(),
});
}
export function trackPerformanceMark(label: string) {
const entry = performance.getEntriesByName(label).pop();
if (entry) {
LogRocket.track("performance-mark", {
label,
duration: Math.round(entry.duration),
startTime: Math.round(entry.startTime),
});
}
}
// Usage
trackFeatureUsage("dashboard-filter", { filterType: "date-range", resultCount: 42 });
trackConversion("subscription-upgrade", 29.99);
Sentry Integration
// lib/logrocket-sentry.ts
import LogRocket from "logrocket";
import * as Sentry from "@sentry/nextjs";
export function connectLogRocketToSentry() {
LogRocket.getSessionURL((sessionURL) => {
Sentry.getCurrentScope().setExtra("logrocket_session", sessionURL);
});
}
// Now every Sentry error event includes a direct link
// to the LogRocket session replay for that user.
Network Request Monitoring
// lib/api-client.ts
import LogRocket from "logrocket";
export async function apiRequest<T>(
url: string,
options?: RequestInit
): Promise<T> {
const start = performance.now();
try {
const response = await fetch(url, options);
const duration = performance.now() - start;
if (!response.ok) {
LogRocket.captureMessage(`API Error: ${response.status} ${url}`, {
tags: {
statusCode: String(response.status),
endpoint: url,
},
extra: {
duration: Math.round(duration),
method: options?.method ?? "GET",
},
});
}
if (duration > 3000) {
LogRocket.track("slow-api-call", {
url,
duration: Math.round(duration),
status: response.status,
});
}
return response.json();
} catch (error) {
LogRocket.captureException(error as Error, {
tags: { type: "network-failure", endpoint: url },
});
throw error;
}
}
Conditional Session Recording
// lib/logrocket-conditional.ts
import LogRocket from "logrocket";
export function initConditionalRecording(userPlan: string) {
// Record all sessions for paid users, sample free users
const shouldRecord =
userPlan !== "free" || Math.random() < 0.1;
if (!shouldRecord) return;
LogRocket.init(process.env.NEXT_PUBLIC_LOGROCKET_APP_ID!, {
shouldDebugLog: false,
});
}
Best Practices
- Sanitize all sensitive inputs — enable
inputSanitizerand userequestSanitizerto strip auth headers and PII from network payloads. - Identify users after login — call
LogRocket.identify()so sessions are searchable by user and you can measure impact per account. - Connect to your error tracker — pipe the session URL into Sentry, Bugsnag, or your issue tracker so every error links directly to replay.
- Use custom events for funnels —
LogRocket.track()events power conversion funnels in the LogRocket dashboard. - Limit recording in non-production — only initialize in production or explicitly opted-in staging environments.
- Strip Redux auth state — use
stateSanitizerto remove tokens and credentials from the recorded store snapshots. - Monitor slow network calls — track requests over a duration threshold to surface API performance issues from the frontend perspective.
- Set meaningful release versions — tie recordings to deploys so you can filter sessions by release and spot regressions.
Anti-Patterns
- Recording every session without sampling — on high-traffic apps this generates enormous data volumes and costs; sample free-tier users.
- Skipping request sanitization — auth tokens, passwords, and PII in network payloads will be stored in LogRocket if not explicitly redacted.
- Not identifying users — anonymous sessions are hard to search and impossible to correlate with support tickets.
- Initializing on the server — LogRocket is browser-only; importing it in server components or API routes causes crashes.
- Ignoring session URL in error reports — the biggest value of LogRocket is the replay link; if your error tracker does not include it, you lose half the benefit.
- Recording in development — wastes quota and pollutes session data with local testing noise.
- Logging entire Redux state without sanitization — risks exposing secrets and creates unnecessarily large payloads.
Install this skill directly: skilldb add monitoring-services-skills
Related Skills
New Relic
New Relic: APM, distributed tracing, browser monitoring, custom events, NRQL queries, alert policies, Node.js and browser agents
Opentelemetry
OpenTelemetry provides a set of open-source APIs, SDKs, and tools to instrument, generate, collect, and export telemetry data (metrics, logs, traces) for observability. Use it to standardize your application's telemetry across various services and vendors without vendor lock-in.
Prometheus
Open-source monitoring and alerting toolkit for collecting metrics via pull-based scraping, building PromQL queries, setting up alerts, and instrumenting applications for cloud-native observability.
Sentry
Sentry: error tracking, performance monitoring, session replay, source maps, breadcrumbs, Next.js/React SDK, alerts
Uptime Robot
Uptime Robot: uptime monitoring API, HTTP/keyword/ping checks, status pages, alert contacts, maintenance windows
Baselime
Baselime is a serverless-native observability platform designed for AWS, unifying logs, traces, and metrics. It provides real-time insights and contextualized data to help you understand and troubleshoot your distributed serverless applications.