- JavaScript errors affect up to 10% of production sessions but 95% go unreported by users
- Error tracking captures the error message, stack trace, browser context, and (with session replay) the exact user actions that triggered it
- The most impactful errors to fix first are those that block conversion actions (checkout, signup, form submission)
- Combining error tracking with session recording gives developers full reproduction steps without asking the user
- Source maps are critical—without them, minified stack traces are nearly impossible to debug
What is JavaScript Error Tracking?
JavaScript error tracking (also called client-side error monitoring, JS error logging, or frontend error reporting) is the practice of automatically capturing, categorizing, and alerting on JavaScript errors that occur in your users' browsers. It's the frontend equivalent of server-side error logging—but significantly harder because errors happen on devices you don't control.
Without error tracking, your only feedback mechanism is users contacting support (rare), your QA team catching bugs (incomplete), or sudden drops in analytics metrics that trigger an investigation days after the bug shipped.
With error tracking, you know within minutes when a new JavaScript error starts affecting users. You see the error message, stack trace, browser details, and—with the right tools—a session recording showing exactly what the user was doing when the error occurred.
Types of JavaScript Errors
Understanding the categories helps you prioritize and respond to errors effectively:
Runtime Errors
These occur while JavaScript is executing. They're the most common and include:
- TypeError — accessing a property on
nullorundefined, calling a non-function. This is the #1 JavaScript error in production. - ReferenceError — using a variable that hasn't been declared. Often caused by loading order issues or typos.
- RangeError — numeric value out of range, most commonly from infinite recursion blowing the call stack.
- SyntaxError — rare in production (caught at parse time), but can appear when
eval()ornew Function()receive malformed input.
Unhandled Promise Rejections
When an async function or Promise rejects without a .catch() handler, the browser fires an unhandledrejection event. These are increasingly common as more code moves to async patterns and are just as impactful as synchronous errors but often harder to trace because the stack trace may not reflect the original caller.
Network and API Errors
Failed fetch() calls, CORS rejections, timeout errors, and HTTP 4xx/5xx responses from your API. These aren't JavaScript "errors" in the technical sense (no Error object is thrown), but they directly impact user experience and should be tracked alongside runtime errors.
Third-Party Script Errors
Errors from scripts you don't control: ad networks, analytics tags, chat widgets, A/B testing tools. These are the noisiest category and often show up as "Script error." with no stack trace due to same-origin policy restrictions. They're important to monitor but should be filtered separately from your own code errors.
How JavaScript Error Tracking Works
Capture Mechanisms
Error tracking tools use three primary browser APIs to capture errors:
// 1. Global error handler — catches synchronous runtime errors
window.onerror = function(message, source, lineno, colno, error) {
reportError({ message, source, lineno, colno, stack: error?.stack });
};
// 2. Unhandled promise rejection handler
window.addEventListener('unhandledrejection', function(event) {
reportError({ message: event.reason?.message, stack: event.reason?.stack });
});
// 3. Console error interception (optional, more aggressive)
const originalError = console.error;
console.error = function(...args) {
reportError({ message: args.join(' '), type: 'console.error' });
originalError.apply(console, args);
};
Modern error tracking tools wrap these with additional context collection: current URL, DOM state, browser info, user session ID, and the sequence of user actions leading up to the error.
Source Maps: The Critical Piece
In production, your JavaScript is minified and bundled. A stack trace pointing to app.min.js:1:28472 is useless for debugging. Source maps translate minified positions back to the original source file, line, and column.
Your error tracking tool needs access to your source maps to show readable stack traces. Most tools accept source maps via:
- File upload during your build/deploy process
- Publicly hosted source maps (with security considerations)
- API upload as part of your CI/CD pipeline
Don't expose source maps publicly in production unless you're comfortable with anyone reading your un-minified source code. Upload them privately to your error tracking tool instead, and configure your bundler to not include the //# sourceMappingURL comment in production builds.
Grouping and Deduplication
A single bug can generate thousands of identical error events. Good error tracking tools group these into unique error types based on the error message, stack trace signature, and source location. This turns 10,000 raw error events into "TypeError in checkout.js:142 — affecting 2,300 users" which is immediately actionable.
The Power of Error Tracking + Session Replay
Error tracking tells you what broke and where in the code. But it doesn't tell you what the user was doing when it broke. Was it a specific sequence of actions? A particular device or browser? A race condition from fast navigation?
When error tracking is combined with session recording, every error event links to a full session replay showing:
- The exact clicks, scrolls, and form inputs leading up to the error
- The page state (DOM) at the moment of the error
- Network requests that succeeded or failed before the error
- Whether the user recovered or abandoned the page
This transforms debugging from "reproduce the bug" (often impossible with limited information) to "watch the bug happen" (complete reproduction in 30 seconds).
Error Logging + Session Replay
Every JS error captured with a full session replay. See exactly what the user did when the error occurred.
How to Prioritize Which Errors to Fix
Not all errors are equal. Here's a framework for prioritization:
The Error Priority Matrix
| Priority | Criteria | Example | Response |
|---|---|---|---|
| P0 — Critical | Blocks a conversion action for many users | TypeError in checkout form handler | Fix immediately, hotfix if needed |
| P1 — High | Breaks a feature for a user segment | Error on Safari-only due to API difference | Fix in current sprint |
| P2 — Medium | Degrades experience but has a workaround | Tooltip fails to render on hover | Prioritize in backlog |
| P3 — Low | Minor or affects very few users | Console error from deprecated API in IE11 | Track, fix when convenient |
Prioritize by user impact, not error frequency. An error affecting 100 users during checkout is far more critical than an error affecting 10,000 users on a decorative animation.
Setting Up JavaScript Error Tracking
Step 1: Install an Error Tracking Tool
Add the error tracking script to your website. With Inspectlet, error logging is built into the same script that handles session recording—no additional installation needed. Other dedicated error tracking tools (Sentry, Bugsnag, Rollbar) require a separate SDK.
Step 2: Upload Source Maps
Configure your build pipeline to generate and upload source maps. For webpack:
// webpack.config.js
module.exports = {
devtool: 'hidden-source-map', // generates maps without public URL
// ... after build, upload .map files to your error tracking tool
};
Step 3: Filter Noise
Before you can usefully monitor errors, filter out the noise:
- Third-party errors: Ignore or separate errors from scripts on other domains
- Browser extensions: Errors injected by ad blockers, password managers, and browser extensions
- Bot traffic: Crawlers and scrapers often trigger errors due to missing JavaScript support
- "Script error." Generic cross-origin errors with no actionable information—add
crossorigin="anonymous"to third-party script tags to get real error details
Step 4: Set Up Alerts
Configure alerts for:
- New error types that appear for the first time (catches new bugs immediately)
- Spike in error volume (catches regressions after deploys)
- Errors on critical pages (checkout, signup, payment)
Most Common JavaScript Errors in Production
Based on aggregate data across millions of websites, these are the errors you'll see most often:
TypeError: Cannot read properties of null/undefined— the perennial #1. Usually caused by DOM queries that return null because the element hasn't rendered yet, or API responses with unexpected null fields.TypeError: x is not a function— often a loading order issue where you call a function before its script has loaded, or a minification/tree-shaking issue that removed a required export.ReferenceError: x is not defined— typically from conditional script loading where a global variable is expected but its script failed to load (ad blockers are a common cause).ChunkLoadError/Loading chunk X failed— code splitting failures, often from cached HTML referencing deleted chunk files after a new deploy. Solved with proper cache-busting and retry logic.NetworkError/Failed to fetch— API calls that fail due to network issues, CORS misconfiguration, or server errors.
Best Practices
- Make error tracking part of your deploy process. Check the error dashboard within 30 minutes of every deploy. New errors appearing right after a release are almost certainly caused by that release.
- Assign ownership. Every P0/P1 error should have an owner who's accountable for fixing it. Unowned errors stay unfixed.
- Track error resolution metrics. Measure mean time to detect (MTTD) and mean time to resolve (MTTR) for critical errors. These are key indicators of your team's reliability practices.
- Use error budgets. Set a target: "No more than 0.5% of sessions should encounter a JavaScript error." When you exceed the budget, stop shipping features and fix bugs.
- Link errors to business impact. Connect error data to revenue metrics. "This checkout error affects 200 users/day at an average cart value of $80" makes the business case instantly clear.
Frequently Asked Questions
Do I need a separate error tracking tool if I already have session recording?
It depends on your needs. Tools like Inspectlet include error logging as part of session recording, which is ideal because you can immediately watch the session where an error occurred. If you need advanced features like source map processing, issue assignment workflows, or integration with your incident management system, a dedicated tool like Sentry may be a good addition.
How do I handle errors from third-party scripts I can't control?
Separate them. Most error tracking tools let you filter by script source domain. Create a "third-party" error bucket and review it periodically, but don't let it drown out your own code's errors. If a third-party script is causing serious issues, consider lazy-loading it, loading it in an iframe sandbox, or replacing it.
What percentage of JavaScript errors are never reported by users?
Studies consistently show that 95%+ of JavaScript errors go unreported. Users either refresh the page, try a different browser, or simply leave. This makes automatic error tracking essential—user reports are the tip of a very large iceberg.
Will error tracking slow down my website?
Modern error tracking adds negligible overhead. The event listener attachments (window.onerror, unhandledrejection) are native browser APIs with virtually zero cost. The only performance consideration is the error reporting network request, which is sent asynchronously and typically batched.