Skip to main content
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

category
string
required
A short identifier for the type of event (e.g., 'checkout', 'auth', 'navigation')
message
string
required
Human-readable description of what happened
level
string
Severity level: 'debug', 'info', 'warning', 'error'. Defaults to 'info'.
data
object
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

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>;
}