loading

Feature detection

IsSupported

Returns true when the runtime exposes ReportingObserver. Check it before subscribing on browsers you do not control.

C#
if (await reporting.IsSupported())
{
    // safe to subscribe
}
Live sample
feature detection output
Results will appear here when you interact with the samples.

Observe every report

Subscribe

Registers a handler that receives each batch of browser-generated reports. With buffered set to true (the default) reports queued before the observer registered are delivered too.

C#
var subscription = await reporting.Subscribe(reports =>
{
    foreach (var report in reports)
    {
        // report.Type → "deprecation", "intervention", ...
        // report.Url  → the page the report applies to
        // report.Body → type-specific payload as a JsonElement
    }
});

// later, when no longer needed:
await subscription.DisposeAsync();
Live sample
reports output
Results will appear here when you interact with the samples.

Filter report types

Subscribe

Pass a whitelist of report types to receive only what you care about - for example just deprecations, so you learn early when the app relies on an API scheduled for removal.

C#
var subscription = await reporting.Subscribe(
    reports =>
    {
        foreach (var report in reports)
        {
            // only deprecation reports arrive here
        }
    },
    types: ["deprecation"],
    buffered: true);

Reading the report body

BrowserReport

The body shape varies per report type, so it is surfaced as a JsonElement. For a deprecation report, for instance, the body carries the offending API id and a human-readable message.

C#
foreach (var report in reports)
{
    if (report.Type is "deprecation")
    {
        var id = report.Body.GetProperty("id").GetString();
        var message = report.Body.GetProperty("message").GetString();
        // e.g. log it, or forward it to your telemetry backend
    }
}
Note:
Reports arrive on the browser's schedule After subscribing, entries appear only when the browser actually generates a report - for example when the page calls a deprecated API or the browser intervenes against an abusive pattern. A quiet console after subscribing simply means this page has given the browser nothing to complain about.
Warning:
Browser support ReportingObserver is available in Chromium-based browsers (Chrome, Edge, Opera); Firefox and Safari do not currently expose it. Use IsSupported before subscribing.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes ReportingObserver.
Subscribe
Task<ButilSubscription> Subscribe(Action<BrowserReport[]> handler, string[]? types = null, bool buffered = true)
Subscribes to browser-generated reports, optionally filtered by type; the returned subscription stops observation when disposed.
InvokeBrowserReport
void InvokeBrowserReport(Guid id, BrowserReport[] reports)
JS interop bridge invoked on each report batch; not intended for application code.
DisposeAsync
ValueTask DisposeAsync()
Disconnects all observers and releases the interop reference.
An unhandled error has occurred. Reload 🗙