Skip to main content
Technology & EngineeringMonitoring Services332 lines

LogRocket

LogRocket: session replay, error tracking, performance monitoring, Redux/Vuex integration, network logging

Quick Summary18 lines
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 lines
Paste into your CLAUDE.md or agent config

LogRocket 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

  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.
  8. Set meaningful release versions — tie recordings to deploys so you can filter sessions by release and spot regressions.

Anti-Patterns

  1. Recording every session without sampling — on high-traffic apps this generates enormous data volumes and costs; sample free-tier users.
  2. Skipping request sanitization — auth tokens, passwords, and PII in network payloads will be stored in LogRocket if not explicitly redacted.
  3. Not identifying users — anonymous sessions are hard to search and impossible to correlate with support tickets.
  4. Initializing on the server — LogRocket is browser-only; importing it in server components or API routes causes crashes.
  5. 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.
  6. Recording in development — wastes quota and pollutes session data with local testing noise.
  7. Logging entire Redux state without sanitization — risks exposing secrets and creates unnecessarily large payloads.

Install this skill directly: skilldb add monitoring-services-skills

Get CLI access →