LogRocket delivers session replay with high-fidelity DOM recording and Redux state inspection — LogRocket.init("APP_ID/SLUG", options) initializes. LogRocket.identify(userId, { email, name, subscriptionType }) associates sessions with users. LogRocket.track("Checkout Started", { cartValue: 49 }) fires a custom event visible in the session timeline. Redux: import createPlugin from "logrocket-redux-middleware", store.dispatch = LogRocket.reduxMiddleware()(store)(store.dispatch) — or add LogRocket.reduxMiddleware() to applyMiddleware. LogRocket.log("Message") / LogRocket.warn() / LogRocket.error() appear in the session console. LogRocket.getSessionURL((url) => Sentry.configureScope((scope) => scope.setExtra("logrocketSession", url))) links LogRocket sessions to Sentry errors. Network recording: captured by default — redact with requestSanitizer and responseSanitizer. Privacy: shouldSanitizeURL callback, dom: { inputSanitizer: true } obscures all inputs, dom: { textSanitizer: true } blocks text. LogRocket React plugin: LogRocket.install() from @logrocket/react catches React errors. window.__LogRocket__ namespace for raw session data. Claude Code generates LogRocket session recording, Redux state capture, and Sentry integration workflows.
CLAUDE.md for LogRocket
## LogRocket Stack
- Version: logrocket >= 8.x, @logrocket/react >= 8.x
- Init: LogRocket.init("org/app-id", { release: GIT_SHA, dom: { inputSanitizer: true }, network: { requestSanitizer, responseSanitizer } })
- Identify: LogRocket.identify(userId, { email, name, plan })
- Track: LogRocket.track("Event Name", { prop: value })
- Log: LogRocket.log("debug msg"); LogRocket.warn("warning"); LogRocket.error("error msg")
- Session URL: LogRocket.getSessionURL(url => /* send to Sentry/support */)
- Redux: applyMiddleware(LogRocket.reduxMiddleware()) in store setup
- Privacy: dom.inputSanitizer: true (obscure inputs), blockClass: "lr-hide" (hides elements)
LogRocket Setup
// lib/logrocket/init.ts — LogRocket initialization with sanitizers
import LogRocket from "logrocket"
import setupLogRocketReact from "@logrocket/react"
let initialized = false
export function initLogRocket() {
if (initialized || typeof window === "undefined") return
LogRocket.init(process.env.NEXT_PUBLIC_LOGROCKET_APP_ID!, {
release: process.env.NEXT_PUBLIC_APP_VERSION ?? "0.0.0",
// Privacy
dom: {
inputSanitizer: true, // obscure all input values
textSanitizer: false, // keep visible text (use .lr-hide class to block selectively)
baseHref: window.location.origin,
},
// Network sanitization
network: {
requestSanitizer: (request) => {
// Redact auth headers
if (request.headers["Authorization"]) {
request.headers["Authorization"] = "[REDACTED]"
}
// Don't record request bodies for auth endpoints
if (request.url.includes("/api/auth")) {
request.body = null
}
return request
},
responseSanitizer: (response) => {
// Don't record response bodies for auth responses
if (response.url?.includes("/api/auth")) {
response.body = null
}
return response
},
},
// Ignore common noise
shouldSanitizeURL: (url) =>
!url.includes("__lr") && !url.includes("logrocket"),
console: {
shouldAggregateConsoleErrors: true,
},
})
setupLogRocketReact(LogRocket)
initialized = true
}
LogRocket Client Utilities
// lib/logrocket/client.ts — typed LogRocket helpers
import LogRocket from "logrocket"
export type UserInfo = {
email?: string
name?: string
plan?: string
company?: string
createdAt?: string
}
export function identifyUser(userId: string, info: UserInfo = {}): void {
if (typeof window === "undefined") return
LogRocket.identify(userId, {
email: info.email ?? "",
name: info.name ?? "",
plan: info.plan ?? "free",
company: info.company ?? "",
createdAt: info.createdAt ?? "",
})
}
// Typed event catalog
type TrackEvents = {
"checkout_started": { cart_value: number; item_count: number }
"checkout_completed": { order_id: string; revenue: number }
"upgrade_attempted": { from_plan: string; to_plan: string }
"feature_activated": { feature: string }
"search_performed": { query: string; result_count: number }
"error_displayed": { error_code: string; page: string }
}
type TrackEventName = keyof TrackEvents
export function track<E extends TrackEventName>(
event: E,
properties: TrackEvents[E],
) {
if (typeof window === "undefined") return
LogRocket.track(event, properties as Record<string, unknown>)
}
/** Get the current session URL for support tickets or Sentry */
export function getSessionURL(): Promise<string> {
return new Promise((resolve) => {
LogRocket.getSessionURL((url) => resolve(url))
})
}
/** Link LogRocket session URL to an external error */
export async function attachSessionToError(
setExtra: (key: string, value: string) => void,
): Promise<void> {
const url = await getSessionURL()
setExtra("logrocketSession", url)
}
Redux Middleware Integration
// lib/store/index.ts — Redux store with LogRocket middleware
import { configureStore } from "@reduxjs/toolkit"
import LogRocket from "logrocket"
import appReducer from "./appSlice"
import userReducer from "./userSlice"
export const store = configureStore({
reducer: {
app: appReducer,
user: userReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(LogRocket.reduxMiddleware()),
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
Next.js Provider
// components/LogRocketProvider.tsx — init + identity + page tracking
"use client"
import { useEffect } from "react"
import { usePathname } from "next/navigation"
import { initLogRocket, identifyUser, track } from "@/lib/logrocket/client"
// Re-export init separately since it needs to be imported
import { initLogRocket as init } from "@/lib/logrocket/init"
type Props = {
userId?: string
userEmail?: string
userPlan?: string
children: React.ReactNode
}
export default function LogRocketProvider({ userId, userEmail, userPlan, children }: Props) {
const pathname = usePathname()
useEffect(() => {
init()
if (userId) {
identifyUser(userId, { email: userEmail, plan: userPlan })
}
}, [userId, userEmail, userPlan])
// Track navigation
useEffect(() => {
LogRocket.log(`[Navigation] ${pathname}`)
}, [pathname])
return <>{children}</>
}
// Add class="lr-hide" to DOM elements you want to block from recording:
// <div className="lr-hide">Credit card number: {cardNumber}</div>
Sentry + LogRocket Integration
// lib/monitoring/index.ts — connect LogRocket sessions to Sentry errors
import * as Sentry from "@sentry/nextjs"
import { getSessionURL } from "@/lib/logrocket/client"
/** Call once after both SDKs are initialized */
export async function linkLogRocketToSentry(): Promise<void> {
const url = await getSessionURL()
Sentry.withScope((scope) => {
scope.setExtra("logRocketSession", url)
scope.setTag("logRocketSessionURL", url)
})
}
/** Capture an error to Sentry with the LogRocket session attached */
export async function captureWithSession(error: Error, context: Record<string, unknown> = {}): Promise<void> {
const sessionURL = await getSessionURL()
Sentry.withScope((scope) => {
scope.setExtra("logRocketSession", sessionURL)
Object.entries(context).forEach(([k, v]) => scope.setExtra(k, v))
Sentry.captureException(error)
})
}
For the OpenReplay alternative when needing a fully open-source, self-hostable session replay tool without any per-session pricing, data leaving your infrastructure, or a dependency on LogRocket’s commercial service — OpenReplay has feature parity with LogRocket for most use cases and can run entirely on your own Kubernetes cluster, see the OpenReplay guide. For the Highlight.io alternative when needing full-stack observability that links frontend session replay to backend error traces and logs via OpenTelemetry — Highlight.io is open-source and ties session replay to distributed traces across both frontend and backend in one tool, while LogRocket focuses exclusively on the frontend experience, see the Highlight.io guide. The Claude Skills 360 bundle includes LogRocket skill sets covering session recording, Redux capture, and Sentry integration. Start with the free tier to try session replay generation.