Tags are session-level metadata — a user segment, an experiment variant, anything that describes the
whole session rather than one moment in it. They show up in the recording's stored metadata
map, alongside the built-in hadError/label fields.
Setting a tag#
final service = PictoService(recording.canvasRecorder);
service.setTag('experiment', 'checkout-redesign-v2');
service.setTag('userSegment', 'power-user');
Call setTag as many times as you like over the session's lifetime — a later call with the same key overwrites the earlier value. Tags aren't part of the recorded byte stream itself; they're merged into the upload's
metadata map automatically when you upload (see below), so there's nothing extra to wire up.
What gets uploaded#
The reference app's upload call includes tags like this:
await uploader.upload(
segment.path,
// ...
metadata: {
'hadError': recording.canvasRecorder.hadError,
'tags': recording.canvasRecorder.tags, // your setTag() calls, if any
},
);
CanvasRecorder.tags is an unmodifiable snapshot of everything you've set via setTag
— read it at upload time, don't try to mutate it directly.
Built-in fields#
One field is populated automatically, independent of anything you tag yourself:
-
hadError—trueifrecordErrorfired at any point in the session (uncaught errors are captured automatically once you callinstallErrorHooks()— see Quick Start).
One key is worth knowing by name because the dashboard treats it specially:
-
label— passmetadata: {'label': 'checkout-regression-run'}toPicto.endSessionAndUploadand the dashboard shows it as a badge on the recording. Useful for naming a whole build or test run rather than tagging programmatically.
When you need more than one tag per moment#
Tags describe the whole session. If you need to mark a specific point in time instead — "checkout button tapped," "payment failed" — see Custom Events.
Identifying which user a session belongs to#
Don't use a tag for this — setTag('userId', ...) would only reach the recording's own metadata, not the exceptions/jank/frustration events it also produces, and the dashboard can't filter on it directly. Use
Picto.identify instead, a dedicated, first-class field built for exactly this.