CanvasKit internals

Session recording on CanvasKit-rendered Flutter web

If you are debugging why session recording returns a blank canvas on Flutter web, the answer is in how the CanvasKit and Skwasm renderers work. Here is the technical picture.

By Pixeltrace · Updated

How Flutter web renders

Flutter web can render through different paths. The production default for most apps is CanvasKit, a WebAssembly build of Skia that draws the entire UI to a WebGL canvas. The newer Skwasm renderer paints to canvas via WebAssembly too. Either way, the output is pixels on a canvas, not an element tree.

This is by design: it gives Flutter pixel-perfect, platform-consistent rendering and the same drawing engine as native. The trade-off for observability tooling is that the semantic structure of the UI is not present in the DOM.

Why DOM recorders return a blank box

rrweb-style recorders (the engine behind PostHog, and conceptually similar to Clarity, Hotjar, FullStory, and LogRocket replay) walk the DOM, snapshot it, and stream subsequent mutations. Open your browser inspector on a CanvasKit app and you can see the problem yourself: under the host element sits a <flt-glass-pane> and a <canvas>, and that is essentially it. The recorder snapshots that one opaque element and has nothing else to stream.

Flutter does expose a semantics tree for accessibility. But it is sparse, tuned for screen readers rather than visual fidelity, and nowhere near enough to reconstruct what the user saw. Even tools that try to read it cannot produce a faithful replay.

The frame-capture approach

The approach that works on CanvasKit is to capture the rendered frames directly, the same pixels Skia draws, and encode them efficiently off the main thread, with privacy masking applied at capture time before anything leaves the device.

Pixeltrace is built around exactly this model for Flutter web. It's in development; join the waitlist to be notified when it's available.

See what your users do in Flutter

Pixeltrace records the frames your Flutter web app paints, so replay works on canvas. It's not generally available yet, so leave your email and we'll tell you the moment it launches.

Help us prioritize (optional)

You'll get one email when Pixeltrace is available. If you want to hear more from us, you'll sign up for that separately (later).

Frequently asked questions

Does the CanvasKit renderer break session replay?
Yes for DOM-based replay. CanvasKit draws the whole UI to a single WebGL canvas, so DOM recorders see one opaque element and cannot reconstruct the interface. Frame-capture-based recording works because it captures the rendered pixels directly.
Can the Flutter accessibility semantics tree be used for replay?
Not for faithful visual replay. The semantics tree is sparse and optimized for screen readers, not visual fidelity, so it cannot reconstruct what the user saw. Capturing rendered frames is required.

Related

← Back to Pixeltrace home