Skip to main content
Beagle’s plugin architecture separates log data from log presentation. Each log type has a corresponding plugin that knows how to display it in the inspector. This design makes Beagle highly extensible and allows custom log types with custom UI.

BeagleLogPlugin Abstract Class

All plugins extend the BeagleLogPlugin abstract class, which defines the contract for rendering logs:

Required Properties and Methods

A unique identifier for the plugin. Used for debugging and display purposes.Example: 'Message', 'Error', 'Networking'
A type guard that determines if this plugin can handle a given log. Beagle uses this to route logs to the correct plugin.Returns: Boolean type predicate that narrows the log type to TExample:
Generates the detailed view content when a log is expanded in the inspector. This is where you define what information is shown and how it’s laid out.Returns: A DetailContent object describing the UI structure

Optional Methods

Optionally provides additional content displayed at the bottom of the log card in the list view.Default: Returns null (no footer)Example use cases:
  • Show request duration for network logs
  • Display stack trace preview for errors
  • Show metadata or tags
Defines how the log should be exported. The default implementation uses JSON.stringify(log).Override this to customize export format or exclude sensitive data.

How Plugins Work

The plugin system follows this flow:

1. Plugin Registration

Plugins are registered during app initialization:
Internally, this adds the plugin to a static array:

2. Log Routing

When a log is displayed, Beagle finds its plugin:
Plugin lookups are cached by log constructor name, so each log type only searches plugins once.

3. Content Generation

The plugin’s methods are called to render the log:
  • List view: provideCardFooter() for additional card content
  • Detail view: provideDetailContent() for the expanded view
  • Export: exportToJSON() when exporting logs

Built-in Plugins

Beagle includes three built-in plugins that demonstrate different rendering strategies:

MessageLogPlugin

The simplest plugin, displaying just the message text:
Key features:
  • Minimal implementation
  • Makes text selectable for copying
  • No footer content

ErrorLogPlugin

Displays error details with stack traces:
Key features:
  • Handles both Error objects and primitive errors
  • Shows error name, message, stack, and cause
  • Preview stack trace in card footer (2 lines)
  • All error details selectable for copying

NetworkingLogPlugin

The most complex plugin, with tabbed interface and rich formatting:
Key features:
  • Tabbed interface (Info, Request, Response)
  • Shows host and duration in footer
  • Renders headers and body for both request and response
  • JSON formatting for request/response bodies
  • Handles loading state for pending requests
The NetworkingLogPlugin demonstrates advanced content types like tabs, sections, and JSON viewers. Use it as a reference when building complex custom plugins.

Plugin Registration with Beagle.registerPlugin()

Plugins must be registered before their log types are used. Registration typically happens in the provider:
Plugins should be registered in a useEffect to ensure they’re only registered once, even if the component re-renders.

Registration Order

Plugins are checked in registration order. If multiple plugins can handle the same log type, the first registered plugin wins. Best practice: Register more specific plugins before generic ones.

Conditional Registration

You can conditionally register plugins based on configuration:

Creating Custom Plugins

To create a custom plugin:
  1. Create a custom log class extending BeagleLog
  2. Create a plugin class extending BeagleLogPlugin<YourLog>
  3. Implement required methods (name, canHandle, provideDetailContent)
  4. Optionally override provideCardFooter and exportToJSON
  5. Register the plugin during app initialization
Example:
This plugin system makes Beagle infinitely extensible while maintaining a consistent user experience.