---
name: ranetrace-javascript-errors
description: Capture client-side JavaScript errors with breadcrumbs, deduplication, and sampling using Ranetrace's Blade directive.
---

# Ranetrace JavaScript error tracking

## When to use this skill

Use this skill when setting up client-side JavaScript error tracking, configuring error filtering, or using the manual JavaScript error capture API.

## Setup

### 1. Enable JavaScript error tracking

```env
RANETRACE_JAVASCRIPT_ERRORS_ENABLED=true
```

### 2. Add the Blade directive

Place `@ranetraceErrorTracking` in your layout, just before the closing `</body>` tag:

```blade
<!DOCTYPE html>
<html>
<head>...</head>
<body>
    {{ $slot }}

    @ranetraceErrorTracking
</body>
</html>
```

The directive injects a self-contained script that automatically captures errors. No npm packages or build steps required.

The same directive also renders the website analytics human-verification beacon when `RANETRACE_WEBSITE_ANALYTICS_BEACON_ENABLED=true`, so one line in the layout installs both. The two are gated separately: with JavaScript error tracking off and the beacon on, the directive renders only the beacon. See the `ranetrace-analytics` skill for what the beacon does and what it requires.

## What gets captured automatically

- **Global errors** via `window.onerror`
- **Unhandled promise rejections**
- **Console errors** (optional, off by default)
- **Breadcrumbs** for debugging context:
  - Page load (the URL the page opened on)
  - User clicks (tag, id, class, text)
  - Form submissions
  - XHR and fetch requests (method, URL, status)

Each error report includes browser info (screen size, viewport, device memory, connection type) and the current URL.

## Manual error capture

The script exposes a global API for manual error tracking:

```javascript
// Capture a caught error
try {
    riskyOperation();
} catch (error) {
    window.Ranetrace.captureError(error, {
        component: 'PaymentForm',
        action: 'submit',
    });
}

// Add a custom breadcrumb
window.Ranetrace.addBreadcrumb('custom', 'User selected plan', {
    plan: 'premium',
    price: 29.99,
});
```

## Configuration

```php
// config/ranetrace.php
'javascript_errors' => [
    'enabled' => env('RANETRACE_JAVASCRIPT_ERRORS_ENABLED', false),
    'queue' => env('RANETRACE_JAVASCRIPT_ERRORS_QUEUE', true),
    'queue_name' => env('RANETRACE_JAVASCRIPT_ERRORS_QUEUE_NAME', null), // unset: the connection's default queue
    'timeout' => env('RANETRACE_JAVASCRIPT_ERRORS_TIMEOUT', 10),
    'sample_rate' => env('RANETRACE_JAVASCRIPT_ERRORS_SAMPLE_RATE', 1.0),
    'capture_console_errors' => env('RANETRACE_JAVASCRIPT_ERRORS_CAPTURE_CONSOLE_ERRORS', false),
    'max_breadcrumbs' => env('RANETRACE_JAVASCRIPT_ERRORS_MAX_BREADCRUMBS', 20),
    'ignored_errors' => [
        'ResizeObserver loop limit exceeded',
        'ResizeObserver loop completed with undelivered notifications',
        'Script error.',
        'Script error',
        'Failed to fetch',
        'NetworkError when attempting to fetch resource',
        'Network request failed',
        'Load failed',
        'Loading chunk',
        'ChunkLoadError',
        'cancelled',
        'canceled',
        'The operation was aborted',
        'AbortError',
        'Illegal invocation',
    ],
],
```

### Key options

- **`sample_rate`**: `1.0` captures 100% of errors, `0.1` captures 10%. Useful for high-traffic sites.
- **`capture_console_errors`**: when `true`, intercepts `console.error()` calls and reports them.
- **`max_breadcrumbs`**: maximum number of breadcrumbs stored per error (default: 20).
- **`ignored_errors`**: error messages containing any of these strings are silently dropped. Add your own patterns as needed.

## Endpoint & throttling

Errors are sent to `POST /ranetrace/javascript-errors/store` (route name `ranetrace.javascript-errors.store`). The route is auto-registered when JS error tracking is enabled, with `web` middleware (CSRF: the injected script sends the host page's `X-CSRF-TOKEN`) plus `throttle`. The default rate limit is `60,1` (60 requests/minute), keyed by the authenticated user's id when present, otherwise the client IP. Tune it via `RANETRACE_JAVASCRIPT_ERRORS_THROTTLE` (Laravel `requests,minutes` format).

Client-side deduplication prevents the same error (same message + file + line + column) from being sent more than once per page session.

## Testing

```bash
php artisan ranetrace:test-javascript-errors
```
