Appearance
Options
How to set options
Options are set by calling window.birdeatsbug.setOptions(options: Partial<SDKOptions>)
, which takes an object containing a partial of all options as parameter. The snippet on the installation page already contains a call to the function. setOptions
needs to be called at least once at page load within the snippet to pass publicAppId
, but can be called at any time after with a new subset of options. One call of setOptions
can set one or many options. All properties not explicitly set use the previous value, or fall back to the default value.
The options object
ts
interface SDKOptions extends SDKDefaultOptions {
publicAppId: string
instantReplay?: boolean = false
recordVideo?: boolean = false
user?: {
email?: string
}
integrations?: IntegrationOptions
ui?: UIOptions
hooks?: HooksOptions
recordedEventTypes?: {
[key in RecordedEventTypesOptions]: boolean
}
}
publicAppId
Is the only mandatory option property without default value. Can be generated in the workspace settings. Without a valid publicAppId
, uploading sessions is not possible.
instantReplay
Boolean which toggles the instant replay feature on or off. It is false
(turned off) by default.
recordVideo
If enabled, the screen is recorded using video instead of a DOM based screen reconstruction. This is helpful in web apps that contain elements that can't be (correctly) recorded with DOM recording, like Canvas. recordVideo
is disabled by default, because:
- Recording video is more resource intensive and results in larger files.
- Not all browsers have the required capability,
getDisplayMedia
. E.g. mobile browsers currently do not support it. At this time, video recording is also not available on desktop Safari, albeit for other reasons. - Screen recording using video is interrupted by page navigation. Hence video recording is most suitable for single page applications.
When recordVideo
is true
and a user starts a screen recording using a browser that does not support getDisplayMedia
, the SDK falls back to DOM recording, as if recordVideo
was not enabled.
user.email
Attaches the email address to the session. If the email input field is not hidden on the preview screen, the user can change this prefilled value before uploading a session.
integrations
Integrations allow SDK to integrate with other popular client-side widgets / tools:
ts
interface IntegrationOptions {
intercom?: boolean = false
zendesk?: boolean = false
}
ui
UI options allow to customize the look, displayed copy, and screen flow. The default flow is described here.
ts
interface UIOptions {
theme: 'light' | 'dark' = 'dark'
position: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' = 'bottom-right'
watermark: boolean = true
defaultButton:
| {
icon: 'brand' | 'exclamation' | false = 'brand'
}
| false = {
icon: 'brand',
}
recordingControls: boolean = true
previewScreen:
| {
visualProof: 'optional' | 'required' | false = 'optional'
visualProofButtons: {
screenshot: boolean = true
screenRecording: boolean = true
} = {
screenshot: true,
screenRecording: true,
}
email: 'optional' | 'required' | false = 'required'
title: 'optional' | 'required' | false = 'optional'
description: 'optional' | 'required' | false = 'optional'
}
| false = {
visualProof: 'optional',
visualProofButtons = {
screenshot: true,
screenRecording: true,
},
email: 'required',
title: 'optional',
description: 'optional',
}
submitConfirmationScreen:
| {
sessionLink: boolean
}
| false = {
sessionLink: false,
}
text: {
defaultButton: string = 'Report a bug'
dismissButton: string = 'Dismiss'
recordingControls: {
starting: string = 'Starting...'
recording: string = 'Recording...'
recordingProgress: string = 'Recording for'
stopRecordingButton: string = 'Stop recording'
}
previewScreen: {
title: string = 'Report a bug'
visualProofMissingErrorMessage: string = 'Please add a visual proof to complete your report.'
startScreenRecordingButton: string = 'Start recording'
takeScreenshotButton: string = 'Take screenshot'
replaceVisualProofButton: string = 'Replace'
removeVisualProofButton: string = 'Remove'
confirmVisualProofRemovalButton: string = 'Confirm removal'
cancelButton: string = 'Cancel'
emailInputPlaceholder: string = 'Add an email'
titleInputPlaceholder: string = 'Add a title'
descriptionInputPlaceholder: string = 'Add a description'
collectionInputPlaceholder: string = 'Select collection'
labelInputPlaceholder: string = 'Select labels'
inputOptional: string = 'optional'
submitButton: string = 'Submit'
uploadError: string = 'Error. Try again'
}
submitConfirmationScreen: {
title: string = 'Bug report submitted'
message: string = 'Thanks for reporting this issue to us. A member of the team will investigate this and get back to you soon.'
copyLink: string = 'Copy link to your bug report'
copiedLink: string = '✓ Link copied!'
confirmationButton: string = 'Close'
}
}
}
hooks
Hook functions allow to define custom behavior within specific parts of the SDK lifecycle:
ts
interface HooksOptions {
afterInit({
isBrowserSupported,
isScreenshotSupported,
isVideoRecordingSupported,
triggerButtons,
}: {
isBrowserSupported: boolean
isScreenshotSupported: boolean
isVideoRecordingSupported: boolean
triggerButtons: HTMLElement[]
}): void
onTrigger(): Promise<void>
afterTrigger(): void
beforeScreenshot(): void
beforeRecording(): void
afterScreenshot(sessionDataPromise: Promise<SessionData>): void
afterRecording(sessionDataPromise: Promise<SessionData>): void
beforeUpload(sessionData: SessionData): Promise<SessionData>
afterUpload(sessionData: SessionData): Promise<void>
afterClose(): void
}
interface SessionData {
session: Session
events: (ClickEvent | ConsoleEvent | NavigationEvent)[]
domEvents: DomEvent[]
networkRequests: NetworkEvent[]
screenshot: undefined | string
video: undefined | string
}
interface Session {
id: string
title?: string
description?: string
hostname: string
userAgent: string
browserName: string
browserVersion: string
browserEngineName: string
browserEngineVersion: string
deviceType: string
deviceVendor: string
osName: string
osVersion: string
screenWidth: number
screenHeight: number
windowWidth: number
windowHeight: number
locale: string
startedAt?: ReturnType<Date['toISOString']>
internetSpeedInMbps?: number
internetLatencyInMs?: number
uploaderEmail?: string
uploadMethod: 'sdk'
link?: string
videoMimeType?: string
videoDuration?: number
videoWidth?: string
videoHeight?: string
}
recordedEventTypes
The recordedEventTypes
object allows to define, which technical data is recorded by the SDK:
ts
interface RecordedEventTypesOptions {
click: boolean = true
keystrokes: boolean = true
'error-uncaught': boolean = true
'error-promise': boolean = true
localStorage: boolean = true
sessionStorage: boolean = true
network:
| false
| Partial<{
maxSizeInBytes: number = 100000
}> = {
maxSizeInBytes: number = 100000
}
dom: boolean | object = true
console:
| false
| Partial<{
debug: boolean = true
log: boolean = true
info: boolean = true
warn: boolean = true
error: boolean = true
assert: boolean = true
trace: boolean = true
dir: boolean = true
group: boolean = true
table: boolean = true
count: boolean = true
profile: boolean = true
time: boolean = true
}> = {
debug: true,
log: true,
info: true,
warn: true,
error: true,
assert: true,
trace: true,
dir: true,
group: true,
table: true,
count: true,
profile: true,
time: true,
}
}
The dom
key is a special case:
- When set to
false
, DOM mutation recording is disabled. - When an object is passed, it allows to override the rrweb options which SDK passes by default. The passed object must be a
Partial<recordOptions>
.
See DOM recording documentation for additional details about DOM recording.