Skip to content

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 = '&check; 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.