React Logging Best Practices for Production
Client-side logging is often overlooked, but it's essential for debugging production issues. Here's how to set it up properly.
Create a Logging Service
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
class Logger {
private level: LogLevel;
private buffer: Array<LogEntry> = [];
private flushInterval: number;
constructor() {
this.level = process.env.NODE_ENV === 'production' ? 'warn' : 'debug';
this.flushInterval = window.setInterval(() => this.flush(), 30000);
}
info(message: string, data?: Record<string, unknown>) {
this.log('info', message, data);
}
error(message: string, error?: Error, data?: Record<string, unknown>) {
this.log('error', message, {
...data,
stack: error?.stack,
errorMessage: error?.message,
});
this.flush(); // Flush errors immediately
}
private log(level: LogLevel, message: string, data?: Record<string, unknown>) {
const entry = {
level,
message,
timestamp: new Date().toISOString(),
url: window.location.href,
...data,
};
if (process.env.NODE_ENV !== 'production') {
console[level](message, data);
}
this.buffer.push(entry);
}
private async flush() {
if (this.buffer.length === 0) return;
const entries = [...this.buffer];
this.buffer = [];
await fetch('/api/logs', {
method: 'POST',
body: JSON.stringify(entries),
}).catch(() => {
this.buffer.unshift(...entries); // Re-queue on failure
});
}
}
export const logger = new Logger();Log User Actions
function useActionLogger() {
return useCallback((action: string, data?: Record<string, unknown>) => {
logger.info(`user_action: ${action}`, {
...data,
sessionId: getSessionId(),
route: window.location.pathname,
});
}, []);
}
// Usage
function CheckoutButton({ orderId }) {
const logAction = useActionLogger();
return (
<button onClick={() => {
logAction('checkout_clicked', { orderId });
processCheckout(orderId);
}}>Checkout</button>
);
}What to Log
- User navigation — page views and route changes
- API failures — status codes, endpoints, response times
- Feature usage — which features are actually used
- Performance events — slow renders, long tasks
What NOT to Log
- Passwords, tokens, personal data
- Every keystroke or mouse movement
- Successful routine API calls (too noisy)
Combine client-side logging with Bugsly's error tracking for complete visibility. Logs show what happened; Bugsly shows what went wrong.
Try Bugsly Free
AI-powered error tracking that explains your bugs. Set up in 2 minutes, free forever for small projects.
Get Started FreeRelated Articles
How to Catch Broken Releases Before Users Report Them
A practical guide to using error tracking, release tagging, and automated alerts to detect broken deploys within minutes — not after user complaints.
Read moreExpress.js Logging Best Practices for Production
Implement structured logging in Express.js with Winston, request correlation IDs, sensitive data filtering, and log level management.
Read morePHP Performance Monitoring Best Practices
Optimize PHP application performance with OPcache tuning, query monitoring, profiling tools, and real-time performance alerting strategies.
Read moreRemix Performance Monitoring Best Practices
Monitor Remix application performance with loader timing, action profiling, streaming metrics, and server-side rendering optimization.
Read more