Collectors
The agent produces assertion results but doesn't decide where they go — that's the collector's job. A collector is a function that receives each assertion payload and does something with it (POST to a backend, log to the console, render in an overlay).
Two official collectors ship as separate packages:
| Package | Purpose | Production use |
|---|---|---|
@faultsense/panel-collector |
Shadow-DOM overlay showing real-time pass/fail + X-Ray element inspector | Dev/staging |
@faultsense/console-collector |
Logs each result as a collapsible devtools group | Dev/staging |
For production, point collectorURL at your collector backend URL with an apiKey. The dev collectors are for local instrumentation and debugging.
Script tag
Load the collector script before the agent script so it registers itself before the agent reads data-collector-url:
<!-- Panel collector -->
<script src="https://cdn.faultsense.com/v0/faultsense-panel.min.js" defer></script>
<script
id="fs-agent"
src="https://cdn.faultsense.com/v0/faultsense-agent.min.js"
data-collector-url="panel"
data-release-label="2.4.1"
defer>
</script>
<!-- Console collector -->
<script src="https://cdn.faultsense.com/v0/faultsense-console.min.js" defer></script>
<script
id="fs-agent"
src="https://cdn.faultsense.com/v0/faultsense-agent.min.js"
data-collector-url="console"
data-release-label="dev"
defer>
</script>
The collector scripts self-register under window.Faultsense.collectors using their name ("panel" or "console"). When the agent sees a non-URL value in data-collector-url, it looks up the registered collector by that name.
Production backend
Point directly at your collector endpoint — no collector package needed:
<script
id="fs-agent"
src="https://cdn.faultsense.com/v0/faultsense-agent.min.js"
data-collector-url="https://collector.example.com/events"
data-api-key="fs_secret_..."
data-release-label="2.4.1"
defer>
</script>
npm
Install the collector alongside the agent:
npm install @faultsense/agent @faultsense/panel-collector
or
npm install @faultsense/agent @faultsense/console-collector
Explicit wiring (recommended)
Import the collector function and pass it as collectorURL:
import { init } from '@faultsense/agent';
import { panelCollector } from '@faultsense/panel-collector';
init({
releaseLabel: '2.4.1',
collectorURL: panelCollector,
});
import { init } from '@faultsense/agent';
import { consoleCollector } from '@faultsense/console-collector';
init({
releaseLabel: 'dev',
collectorURL: consoleCollector,
});
No apiKey is needed when collectorURL is a function — the collector receives payloads directly in-process.
Auto wiring
If you prefer script-tag parity inside a bundler, use the auto imports:
import '@faultsense/panel-collector/auto';
import '@faultsense/agent/auto';
The collector's auto entry self-registers under window.Faultsense.collectors, and the agent's auto entry reads data-collector-url from the <script id="fs-agent"> tag. This is the same mechanism the script-tag path uses.
Production backend (npm)
Pass the URL string directly — no collector package:
import { init } from '@faultsense/agent';
init({
releaseLabel: '2.4.1',
collectorURL: 'https://collector.example.com/events',
apiKey: 'fs_secret_...',
});
Peer dependencies
Both collector packages declare @faultsense/agent as a peerDependency, not a direct dependency. This prevents your bundler from resolving two separate copies of the agent — which would silently break collector lookup because window.Faultsense.collectors is a shared registry, and two copies would set up two independent registries.
If your package manager warns about an unmet peer dependency, install @faultsense/agent directly:
npm install @faultsense/agent @faultsense/panel-collector
Custom collectors
Any function with the signature (payload: ApiPayload) => void works as a collector:
import { init } from '@faultsense/agent';
import type { ApiPayload } from '@faultsense/agent';
function myCollector(payload: ApiPayload): void {
fetch('/my-endpoint', {
method: 'POST',
body: JSON.stringify(payload),
headers: { 'Content-Type': 'application/json' },
});
}
init({
releaseLabel: '2.4.1',
collectorURL: myCollector,
});
See the payload spec for the full ApiPayload shape.