While automatic breadcrumbs capture technical events, custom breadcrumbs let you add business-specific context that helps you understand the user’s intent.
Adding Custom Breadcrumbs
Proliferate . addBreadcrumb ( category , message , level , data );
Parameters
A short identifier for the type of event (e.g., 'checkout', 'auth', 'navigation')
Human-readable description of what happened
Severity level: 'debug', 'info', 'warning', 'error'. Defaults to 'info'.
Additional key-value data to include
Basic Usage
Proliferate . addBreadcrumb ( 'checkout' , 'User started checkout' , 'info' , {
cart_items: 3 ,
cart_total: 99.99 ,
});
Use Cases
User Journey Tracking
// User adds item to cart
Proliferate . addBreadcrumb ( 'cart' , 'Item added to cart' , 'info' , {
product_id: 'prod_123' ,
quantity: 1 ,
price: 29.99 ,
});
// User proceeds to checkout
Proliferate . addBreadcrumb ( 'checkout' , 'Checkout started' , 'info' , {
cart_size: 3 ,
cart_total: 89.97 ,
});
// User enters shipping info
Proliferate . addBreadcrumb ( 'checkout' , 'Shipping info entered' , 'info' , {
shipping_method: 'express' ,
});
// User attempts payment
Proliferate . addBreadcrumb ( 'checkout' , 'Payment attempted' , 'info' , {
payment_method: 'card' ,
});
State Changes
// Form validation
Proliferate . addBreadcrumb ( 'form' , 'Form submitted' , 'info' , {
form_name: 'signup' ,
fields_count: 5 ,
});
// Modal interactions
Proliferate . addBreadcrumb ( 'ui' , 'Modal opened' , 'info' , {
modal_id: 'confirm-delete' ,
});
// Feature flags
Proliferate . addBreadcrumb ( 'feature' , 'Feature flag evaluated' , 'debug' , {
flag: 'new_checkout' ,
value: true ,
});
Error Context
// Before risky operations
Proliferate . addBreadcrumb ( 'api' , 'Calling payment API' , 'info' , {
amount: 99.99 ,
currency: 'USD' ,
});
try {
await processPayment ( order );
} catch ( error ) {
// Add context about the failure
Proliferate . addBreadcrumb ( 'api' , 'Payment API failed' , 'error' , {
error_type: error . name ,
retry_count: retryCount ,
});
throw error ;
}
Best Practices
Be Specific with Categories
Use consistent, descriptive categories: // Good - specific categories
Proliferate . addBreadcrumb ( 'auth' , 'Login attempted' );
Proliferate . addBreadcrumb ( 'checkout' , 'Order submitted' );
Proliferate . addBreadcrumb ( 'search' , 'Query executed' );
// Bad - vague categories
Proliferate . addBreadcrumb ( 'action' , 'Did something' );
Proliferate . addBreadcrumb ( 'event' , 'Something happened' );
Add data that helps debugging: // Good - actionable context
Proliferate . addBreadcrumb ( 'cart' , 'Item removed' , 'info' , {
product_id: 'prod_123' ,
reason: 'out_of_stock' ,
cart_total_before: 150.00 ,
cart_total_after: 120.00 ,
});
// Less useful - missing context
Proliferate . addBreadcrumb ( 'cart' , 'Item removed' );
Add breadcrumbs at meaningful points, not every line: // Bad - too granular
Proliferate . addBreadcrumb ( 'func' , 'Entering validate()' );
Proliferate . addBreadcrumb ( 'func' , 'Checking email' );
Proliferate . addBreadcrumb ( 'func' , 'Email valid' );
Proliferate . addBreadcrumb ( 'func' , 'Checking password' );
// ...
// Good - meaningful events
Proliferate . addBreadcrumb ( 'validation' , 'Form validated' , 'info' , {
valid: true ,
fields_checked: 5 ,
});
Never include passwords, tokens, or PII: // Bad - sensitive data
Proliferate . addBreadcrumb ( 'auth' , 'Login' , 'info' , {
email: user . email ,
password: user . password , // Never!
});
// Good - safe identifiers only
Proliferate . addBreadcrumb ( 'auth' , 'Login' , 'info' , {
user_id: user . id ,
method: 'password' ,
});
Combining with Automatic Breadcrumbs
Custom breadcrumbs appear alongside automatic ones in the timeline:
Error: Payment declined
────────────────────────────────────────────
Breadcrumbs (8):
14:23:45.100 navigation Navigated to /checkout
14:23:45.200 checkout Checkout started <- Custom
14:23:45.500 fetch GET /api/cart (200, 150ms)
14:23:46.000 checkout Shipping info entered <- Custom
14:23:46.500 checkout Payment method selected: card <- Custom
14:23:47.000 checkout Payment attempted <- Custom
14:23:47.500 fetch POST /api/payments (400, 2s)
14:23:47.600 [ERROR: Payment declined]
TypeScript Types
type BreadcrumbCategory = 'fetch' | 'xhr' | 'console' | 'click' | 'navigation' | string ;
type BreadcrumbLevel = 'debug' | 'info' | 'warning' | 'error' ;
interface Breadcrumb {
timestamp : number ;
category : BreadcrumbCategory ;
message : string ;
level : BreadcrumbLevel ;
data ?: Record < string , unknown >;
}