Custom Trigger
Open the ProductBridge widget from any element on your page — your own button, nav item, or menu link. Initialize with customTrigger and call ProductBridge.toggle() from your element's click handler.
Overview
The custom trigger embed hides the default floating button and lets you open the widget from your own UI. Initialize the SDK with customTrigger: true, then call ProductBridge.toggle() (or ProductBridge.open()) from any click handler — a nav link, a help button, a keyboard shortcut. The widget opens as a full-height sidebar panel.
Use this when you already have a feedback entry point in your UI and don't want two buttons on screen.
How It Works
- Add any clickable element to your page
- Load the SDK and call
ProductBridge.init()withcustomTrigger: true— this hides the floating button - Wire your element's click event to
ProductBridge.toggle()
Installation
<!-- 1. Your custom trigger element — can be any HTML element -->
<button id="feedback-btn">Share Feedback</button>
<!-- 2. Paste before </body> -->
<script>
(function () {
var s = document.createElement('script');
s.src = 'https://app.productbridge.io/sdk/pb-widget.js';
s.async = true;
s.onload = function () {
ProductBridge.init({
organizationId: 'YOUR_ORGANIZATION_ID',
customTrigger: true, // hides the floating button
theme: 'auto',
defaultTab: 'feedback',
});
// 3. Wire your element to the widget
document.getElementById('feedback-btn')
.addEventListener('click', function () {
ProductBridge.toggle();
});
};
document.head.appendChild(s);
})();
</script>
// This component renders your trigger button and wires up the SDK.
// Place it wherever you want the trigger to appear.
import { useEffect, useRef } from 'react';
export default function ProductBridgeCustomTrigger({
organizationId = 'YOUR_ORGANIZATION_ID',
theme = 'auto',
defaultTab = 'feedback',
userToken = null,
children = 'Share Feedback',
}) {
const initialized = useRef(false);
useEffect(() => {
if (initialized.current) return;
initialized.current = true;
const script = document.createElement('script');
script.src = 'https://app.productbridge.io/sdk/pb-widget.js';
script.async = true;
script.onload = () => {
window.ProductBridge.init({
organizationId,
customTrigger: true,
theme,
defaultTab,
...(userToken && { userToken }),
});
};
document.head.appendChild(script);
return () => {
window.ProductBridge?.destroy();
};
}, [organizationId, userToken]);
return (
<button onClick={() => window.ProductBridge?.toggle()}>
{children}
</button>
);
}
// Usage:
// <ProductBridgeCustomTrigger organizationId="YOUR_ID">
// Share Feedback
// </ProductBridgeCustomTrigger>
<!-- Place this component wherever you want the trigger button.
Style the button however you like. -->
<script setup>
import { onMounted, onUnmounted } from 'vue';
const props = defineProps({
organizationId: { type: String, default: 'YOUR_ORGANIZATION_ID' },
theme: { type: String, default: 'auto' },
defaultTab: { type: String, default: 'feedback' },
userToken: { type: String, default: null },
});
onMounted(() => {
const script = document.createElement('script');
script.src = 'https://app.productbridge.io/sdk/pb-widget.js';
script.async = true;
script.onload = () => {
window.ProductBridge.init({
organizationId: props.organizationId,
customTrigger: true,
theme: props.theme,
defaultTab: props.defaultTab,
...(props.userToken && { userToken: props.userToken }),
});
};
document.head.appendChild(script);
});
onUnmounted(() => {
window.ProductBridge?.destroy();
});
function toggleWidget() {
window.ProductBridge?.toggle();
}
</script>
<template>
<button @click="toggleWidget">
<slot>Share Feedback</slot>
</button>
</template>
// Place <app-productbridge-trigger>Share Feedback</app-productbridge-trigger>
// wherever you want the trigger button in your templates.
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
@Component({
selector: 'app-productbridge-trigger',
template: `<button (click)="toggleWidget()"><ng-content></ng-content></button>`,
standalone: true,
})
export class ProductBridgeTriggerComponent implements OnInit, OnDestroy {
@Input() organizationId = 'YOUR_ORGANIZATION_ID';
@Input() theme = 'auto';
@Input() defaultTab = 'feedback';
@Input() userToken?: string;
ngOnInit(): void {
const script = document.createElement('script');
script.src = 'https://app.productbridge.io/sdk/pb-widget.js';
script.async = true;
script.onload = () => {
(window as any).ProductBridge.init({
organizationId: this.organizationId,
customTrigger: true,
theme: this.theme,
defaultTab: this.defaultTab,
...(this.userToken && { userToken: this.userToken }),
});
};
document.head.appendChild(script);
}
toggleWidget(): void {
(window as any).ProductBridge?.toggle();
}
ngOnDestroy(): void {
(window as any).ProductBridge?.destroy();
}
}
Trigger Any Element
You can wire the widget to any existing element on the page — you don't need to render a new button:
<!-- Trigger an existing nav link -->
<a id="nav-feedback-link" href="#">Feedback</a>
<script>
ProductBridge.init({
organizationId: 'YOUR_ORGANIZATION_ID',
customTrigger: true,
});
document.getElementById('nav-feedback-link')
.addEventListener('click', function (e) {
e.preventDefault();
ProductBridge.toggle();
});
</script>
// Or open and close explicitly instead of toggling
document.getElementById('my-help-menu-item')
.addEventListener('click', () => ProductBridge.open());
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
organizationId | string | — | Required. Your organization ID |
customTrigger | boolean | false | Required for this embed type. Set to true to hide the floating button; you open the widget yourself with ProductBridge.toggle() or ProductBridge.open() |
theme | string | auto | auto, light, or dark |
defaultTab | string | feedback | feedback, roadmap, or changelog |
userToken | string | — | JWT for automatic user identification — see Identity Verification |
With customTrigger: true, the SDK hides the floating button entirely and the widget opens as a sidebar panel. It opens only when you call ProductBridge.toggle() or ProductBridge.open() from your own code.
Identify Your Users
To link feedback to your logged-in users, generate a JWT on your backend and pass it as userToken. See Identity Verification for server-side code in Node.js, Python, PHP, Ruby, and Go.