Skip to content

Customization

The sections below describe typical customization examples. To see all options, see the options page.

INFO

If you desire a full custom UI, please get in touch. A premium plan is required.

Default flow and screens

The SDK comes pre-configured with default screens, allowing it to be used without any further customization. The default flow (in the dark theme) is shown in this video, and this diagram below:

Diagram showing default flow and screens

Chose a theme

We offer both a dark and a light theme for the default screens. You can change it by setting the ui.theme option to the desired variant:

window.birdeatsbug.setOptions({
	/* ... other options */
	ui: {
		theme: 'light',
	},
})

Place the default button

You can position the default button in one of the four corners of the browser. You can set its position using the following property:

window.birdeatsbug.setOptions({
	/* ... other options */
	ui: {
		/* can be set to 'top-right', 'top-left', 'bottom-right', or 'bottom-left' */
		position: 'top-right',
	},
})

Change UI text

You can define every UI element's copy by setting the text option object's keys to custom string values:

window.birdeatsbug.setOptions({
	/*...otherOptions, */
	ui: {
		text: {
			defaultButton: 'Report feedback',
		},
	},
})

All available UI text keys are documented here.

Add additional triggers

Any HTML element with the attribute data-birdeatsbug="startSession" that is present in the DOM when the SDK is initialized triggers the SDK flow. For example:

<button data-birdeatsbug="startSession">Share feedback</button>

While this approach works well for static or server side rendered sites, single page applications might add triggers only later. To trigger the SDK flow programatically, call window.birdeatsbug.startSession(), e.g. in the click handler of a button. Before making a call to window.birdeatsbug.startSession(), check whether the end-user's browser is supported, by checking if window.birdeatsbug.isBrowserSupported is true (and, of course, only add triggers programatically if that's the case). Example:

if (window.birdeatsbug.isBrowserSupported) {
	const customButton = document.createElement('button')
	customButton.innerText = 'Share feedback'
	customButton.addEventListener('click', window.birdeatsbug.startSession)
	document.body.appendChild(customButton)
}

Disable the default button

To hide the default button and only use custom triggers, set the ui.defaultButton option to false:

window.birdeatsbug.setOptions({ui: {defaultButton: false}})

Define which fields users need to submit

Besides the (optional) screen recording, end-users can provide up to three inputs in the session's preview screen:

  • Title
  • Description
  • Email address

Each one of these inputs can be configured to be required, optional, or hidden.

window.birdeatsbug.setOptions({
	/*...otherOptions, */
	ui {
		previewScreen: {
			/* title input visible, but optional */
			title: 'optional',
			/* description textarea not visible */
			description: false,
			/* email input needs to be filled */
			email: 'required'
		}
	}
})

Pre-fill / auto-include the user email

If you know the user's email address, you can pass it to the SDK. If the session preview screen is configured to show the email input, it will be pre-filled with the user's email. If the email field is hidden on the session preview screen, the email will still be included in the submission, but the user will not be able to change it.

window.birdeatsbug.setOptions({
	/*...otherOptions, */
	user: {email: 'feedback@birdeatsbug.com'},
})

To disable that the end user is shown the session link after a successful session upload:

window.birdeatsbug.setOptions({
	/* ... other options */
	ui: {
		submitConfirmationScreen: {sessionLink: false},
	},
})

Skip the introduction screen

By default, an introduction screen is shown before screen recording starts. This is helpful for end-users, but might be superfluous when using the SDK in an internal testing system with users who are familiar with Bird Eats Bug. That's why this step can be skipped. The same goes for the success confirmation message after reporting a session.

The following example disables both screens:

window.birdeatsbug.setOptions({
	/*...otherOptions, */
	ui: {
		introductionScreen: false,
		submitConfirmationScreen: false,
	},
})

Integrate with Intercom

The Bird SDK can supplement customer support flows with Intercom. The following configuration will open Intercom and auto-send the Bird session link to customer support via Intercom after the session was uploaded. This allows customer support to respond to the user right away:

window.birdeatsbug.setOptions({
	/* ...otherOptions, */
	ui: {
		submitConfirmationScreen: false,
	},
	hooks: {
		afterUpload: async sessionData => {
			if (!window.Intercom) return
			const session = sessionData.session
			// If the user is not identified in Intercom, but entered an email in SDK, forward the information
			if (!window.intercomSettings.email && session.uploaderEmail) {
				window.intercomSettings.email = session.uploaderEmail
				window.Intercom('boot', window.intercomSettings)
			}
			// Open Intercom and add Bird link with title + description
			let intercomMessage = `Hey, I just reported an issue, here is the link: ${session.link}. `
			if (session.title) intercomMessage += `It is about "${session.title}". `
			if (session.description) intercomMessage += `More details: "${session.description}".`
			window.Intercom('showNewMessage', intercomMessage)
			// Poll for the Intercom iFrame to be open
			let intercomIframe
			while (!intercomIframe) {
				await new Promise(resolve => setTimeout(resolve, 50))
				intercomIframe = document.querySelector("iframe[name='intercom-messenger-frame']")
			}
			let intercomSendMessageButton
			while (!intercomSendMessageButton) {
				intercomSendMessageButton = intercomIframe.contentDocument.querySelector(
					'#intercom-container button.intercom-composer-send-button'
				)
				await new Promise(resolve => setTimeout(resolve, 50))
			}
			// Send the Intercom message
			intercomSendMessageButton.click()
			// Close Intercom again (commented out because of flicker, which could confuse users)
			// window.Intercom('hide')
		},
	},
})

Exclude recording of select data types

Data-rich bug reports are more efficient to debug and resolve. However, there's valid reasons to exclude some events from the bug report, e.g. to protect the privacy of end-users. That's why each recordable event type can be ignored by the recorder when setting its specific recordedEventTypes property to false.

window.birdeatsbug.setOptions({
	/*...otherOptions, */
	recordedEventTypes: {
		/* mouse clicks */
		click: true,
		/* console.debug() calls */
		debug: true,
		/* console.log() calls */
		log: true,
		/* console.info() calls */
		info: true,
		/* console.warn() calls */
		warn: true,
		/* console.error() calls */
		error: true,
		/* console.assert() calls */
		assert: true,
		/* unhandled errors */
		'error-uncaught': true,
		/* promise rejections */
		'error-promise': true,
		/* network requests and responses */
		network: true,
		/* DOM (screen) recording */
		dom: true,
	},
})

Mutate recorded data before upload

The authorization header in network requests is scrubbed automatically. To exclude additional private information, use the beforeUpload hook. The example below removes the password field from network request bodies:

async function removePii(sessionData) {
	sessionData.networkRequests = sessionData.networkRequests.map(request => {
		if (request.requestBody?.password) {
			delete request.requestBody.password
		}
		return request
	})
	return sessionData
}

window.birdeatsbug.setOptions({
	/*...otherOptions, */
	hooks: {
		beforeUpload: removePii,
	},
})

The same hook can also be used to e.g. prefix all session titles reported with SDK:

window.birdeatsbug.setOptions({
	/*...otherOptions, */
	hooks: {
		beforeUpload: sessionData => {
			if (sessionData.session.title) {
				sessionData.session.title = 'SDK: ' + sessionData.session.title
			}
			return sessionData
		},
	},
})