Help Center / Widget SDK
Custom widget integrations
Integrate the UserJot widget with your own UI components and workflows.
Custom trigger buttons
Replace the default floating button with your own design.
Basic custom button
// Initialize with custom trigger
window.uj.init('YOUR_PROJECT_ID', {
widget: true,
trigger: 'custom' // Hides default button
});
// Open widget with your button
document.getElementById('feedback-btn').onclick = () => {
window.uj.showWidget();
};
Multiple trigger points
Add feedback triggers throughout your application:
// Header feedback button
document.querySelector('.header-feedback').onclick = () => {
window.uj.showWidget({ section: 'feedback' });
};
// Footer roadmap link
document.querySelector('.footer-roadmap').onclick = () => {
window.uj.showWidget({ section: 'roadmap' });
};
// Help menu updates option
document.querySelector('.help-updates').onclick = () => {
window.uj.showWidget({ section: 'updates' });
};
Conditional display
Show the widget based on user actions or application state.
Show after user action
// Show after task completion
function onTaskComplete() {
setTimeout(() => {
window.uj.showWidget({ section: 'feedback' });
}, 2000);
}
// Show on error
window.addEventListener('error', (event) => {
if (event.error?.userFacing) {
window.uj.showWidget({ section: 'feedback' });
}
});
Show based on user segment
// Show for specific user types
if (user.plan === 'premium' && user.daysActive > 30) {
window.uj.setWidgetEnabled(true);
} else {
window.uj.setWidgetEnabled(false);
}
State synchronization
Keep your app in sync with widget state.
Track widget visibility
// Monitor widget state changes
let previousState = { isOpen: false, section: null };
setInterval(() => {
const currentState = window.uj.getWidgetState();
if (currentState.isOpen !== previousState.isOpen) {
// Widget opened or closed
analytics.track('Widget Toggled', {
isOpen: currentState.isOpen,
section: currentState.section
});
}
previousState = currentState;
}, 1000);
Coordinate with modals
// Close widget when opening modal
function openModal() {
window.uj.hideWidget();
// Show your modal
}
// Check widget before showing modal
function showModal() {
const state = window.uj.getWidgetState();
if (state.isOpen) {
window.uj.hideWidget();
setTimeout(showModal, 300); // Wait for animation
} else {
// Show modal
}
}
Framework integrations
React
// Custom hook
function useUserJot() {
const [widgetState, setWidgetState] = useState({
isOpen: false,
section: null
});
useEffect(() => {
const interval = setInterval(() => {
setWidgetState(window.uj.getWidgetState());
}, 500);
return () => clearInterval(interval);
}, []);
const showWidget = (section) => {
window.uj.showWidget({ section });
};
const hideWidget = () => {
window.uj.hideWidget();
};
return { widgetState, showWidget, hideWidget };
}
// Component usage
function FeedbackButton() {
const { widgetState, showWidget, hideWidget } = useUserJot();
return (
<button
onClick={() =>
widgetState.isOpen ? hideWidget() : showWidget('feedback')
}
>
{widgetState.isOpen ? 'Close' : 'Feedback'}
</button>
);
}
Vue
<template>
<button @click="toggleWidget">
{{ widgetOpen ? 'Close' : 'Send Feedback' }}
</button>
</template>
<script>
export default {
data() {
return {
widgetOpen: false
};
},
methods: {
toggleWidget() {
if (this.widgetOpen) {
window.uj.hideWidget();
} else {
window.uj.showWidget({ section: 'feedback' });
}
this.widgetOpen = !this.widgetOpen;
}
},
mounted() {
// Check state periodically
setInterval(() => {
const state = window.uj.getWidgetState();
this.widgetOpen = state.isOpen;
}, 500);
}
};
</script>
Angular
@Component({
selector: 'app-feedback',
template: `
<button (click)="toggleWidget()">
{{ getButtonText() }}
</button>
`
})
export class FeedbackComponent implements OnInit {
widgetState = { isOpen: false, section: null };
ngOnInit() {
// Poll widget state
interval(500).subscribe(() => {
this.widgetState = (window as any).uj.getWidgetState();
});
}
toggleWidget() {
if (this.widgetState.isOpen) {
(window as any).uj.hideWidget();
} else {
(window as any).uj.showWidget({ section: 'feedback' });
}
}
getButtonText() {
return this.widgetState.isOpen ? 'Close' : 'Feedback';
}
}
Analytics integration
Track widget interactions for insights.
// Track widget events
function trackWidgetEvent(action, data = {}) {
// Your analytics tool
analytics.track(`Widget ${action}`, {
...data,
timestamp: Date.now()
});
}
// Track opens
document.querySelector('.feedback-trigger').onclick = () => {
trackWidgetEvent('Opened', {
trigger: 'custom_button',
section: 'feedback'
});
window.uj.showWidget({ section: 'feedback' });
};
// Track state changes
let lastState = { isOpen: false };
setInterval(() => {
const state = window.uj.getWidgetState();
if (state.isOpen && !lastState.isOpen) {
trackWidgetEvent('Opened', {
section: state.section
});
} else if (!state.isOpen && lastState.isOpen) {
trackWidgetEvent('Closed', {
lastSection: lastState.section
});
}
lastState = state;
}, 1000);
Keyboard shortcuts
Add keyboard shortcuts to open the widget.
document.addEventListener('keydown', (e) => {
// Cmd/Ctrl + K to open feedback
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
const state = window.uj.getWidgetState();
if (state.isOpen) {
window.uj.hideWidget();
} else {
window.uj.showWidget({ section: 'feedback' });
}
}
});
UserJot
Last updated on August 13, 2025.