Capture client-side JavaScript errors with breadcrumbs, deduplication, and sampling using Ranetrace's Blade directive.
php artisan boost:add-skill ranetrace/ranetrace-laravel
Save this content to: .claude/skills/ranetrace-javascript-errors/SKILL.md
# 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
```
Use this skill when setting up client-side JavaScript error tracking, configuring error filtering, or using the manual JavaScript error capture API.
RANETRACE_JAVASCRIPT_ERRORS_ENABLED=true
Place @ranetraceErrorTracking in your layout, just before the closing </body> tag:
<!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.
window.onerrorEach error report includes browser info (screen size, viewport, device memory, connection type) and the current URL.
The script exposes a global API for manual error tracking:
// 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,
});
// 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',
],
],
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.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.
php artisan ranetrace:test-javascript-errors
How can I help you explore Laravel packages today?