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
Track up to 100 issues per month on the free plan; events are not billed.
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 moreFrom the same team
SEOBolt
Technical SEO and AI search audits with ready-to-apply fix plans.
Try SEOBolt →GrowFast
Domain in, qualified B2B leads out, with cold outreach and deliverability handled.
Try GrowFast →AutoShort
Turn a topic into a faceless short: AI script, voiceover and captions.
Try AutoShort →RemixViral
Paste a long video and get back the moments worth posting, cut vertical and captioned.
Try RemixViral →