Events
Learn how to listen for and respond to SDK events in the Feedhog JavaScript SDK.
Events
The Feedhog SDK emits events when important actions occur. Use event listeners to react to user actions, track analytics, or update your UI.
Event Types
| Event | Payload | Description |
|---|---|---|
identify | IdentifiedUser | User was successfully identified |
submit | FeedbackListItem | Feedback was submitted |
vote | { feedbackId: string, result: VoteResult } | Vote was toggled |
error | Error | An error occurred |
reset | undefined | User data was cleared |
on(event, handler)
Subscribe to an event:
feedhog.on(event: string, handler: (payload: unknown) => void): voidoff(event, handler)
Unsubscribe from an event:
feedhog.off(event: string, handler: (payload: unknown) => void): voidEvent Examples
identify Event
Fired when a user is successfully identified:
import Feedhog from '@feedhog/js';
import type { IdentifiedUser } from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
feedhog.on('identify', (user: IdentifiedUser) => {
console.log('User identified:', user.id);
console.log('Email:', user.email);
console.log('Created at:', user.createdAt);
// Track in analytics
analytics.identify(user.id, {
email: user.email,
name: user.name
});
});
// Trigger the event
await feedhog.identify({
externalId: 'user-123',
email: 'john@example.com'
});submit Event
Fired when feedback is successfully submitted:
import Feedhog from '@feedhog/js';
import type { FeedbackListItem } from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
feedhog.on('submit', (feedback: FeedbackListItem) => {
console.log('Feedback submitted:', feedback.id);
console.log('Title:', feedback.title);
console.log('Type:', feedback.type);
// Show success notification
toast.success('Thank you for your feedback!');
// Track in analytics
analytics.track('Feedback Submitted', {
feedbackId: feedback.id,
type: feedback.type
});
});
// Trigger the event
await feedhog.submit({
title: 'Add dark mode',
type: 'idea'
});vote Event
Fired when a vote is toggled:
import Feedhog from '@feedhog/js';
import type { VoteResult } from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
feedhog.on('vote', ({ feedbackId, result }: { feedbackId: string; result: VoteResult }) => {
console.log('Vote on:', feedbackId);
console.log('Voted:', result.voted);
console.log('Total votes:', result.voteCount);
// Track in analytics
analytics.track(result.voted ? 'Upvoted' : 'Removed Vote', {
feedbackId,
voteCount: result.voteCount
});
});
// Trigger the event
await feedhog.vote('fb_abc123');error Event
Fired when any SDK operation fails:
import Feedhog from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
feedhog.on('error', (error: Error) => {
console.error('Feedhog error:', error.message);
// Send to error tracking
Sentry.captureException(error);
// Show user-friendly message
toast.error('Something went wrong. Please try again.');
});
// This will trigger the error event
try {
await feedhog.submit({ title: '' }); // Empty title
} catch (error) {
// Error is also thrown, but event is emitted first
}reset Event
Fired when user data is cleared:
import Feedhog from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
feedhog.on('reset', () => {
console.log('User data cleared');
// Clear local state
setCurrentUser(null);
// Track in analytics
analytics.reset();
});
// Trigger the event
feedhog.reset();Removing Event Listeners
Always remove event listeners when they're no longer needed:
import Feedhog from '@feedhog/js';
import type { FeedbackListItem } from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
// Define the handler
function handleSubmit(feedback: FeedbackListItem) {
console.log('Submitted:', feedback.id);
}
// Add listener
feedhog.on('submit', handleSubmit);
// Remove listener when done
feedhog.off('submit', handleSubmit);React Integration
Use events with React hooks:
'use client';
import { useEffect, useCallback } from 'react';
import Feedhog from '@feedhog/js';
import type { FeedbackListItem, IdentifiedUser } from '@feedhog/js';
import { toast } from 'sonner';
const feedhog = new Feedhog({
apiKey: process.env.NEXT_PUBLIC_FEEDHOG_API_KEY!
});
export function useFeedhogEvents() {
const handleIdentify = useCallback((user: IdentifiedUser) => {
console.log('User identified:', user.id);
}, []);
const handleSubmit = useCallback((feedback: FeedbackListItem) => {
toast.success('Feedback submitted!', {
description: feedback.title
});
}, []);
const handleError = useCallback((error: Error) => {
toast.error('Something went wrong', {
description: error.message
});
}, []);
useEffect(() => {
// Add listeners
feedhog.on('identify', handleIdentify);
feedhog.on('submit', handleSubmit);
feedhog.on('error', handleError);
// Cleanup on unmount
return () => {
feedhog.off('identify', handleIdentify);
feedhog.off('submit', handleSubmit);
feedhog.off('error', handleError);
};
}, [handleIdentify, handleSubmit, handleError]);
return feedhog;
}Usage in Components
'use client';
import { useFeedhogEvents } from '@/hooks/use-feedhog-events';
export function FeedbackProvider({ children }: { children: React.ReactNode }) {
// Set up event listeners
useFeedhogEvents();
return <>{children}</>;
}Analytics Integration
Track all Feedhog events in your analytics provider:
import Feedhog from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
// Identify
feedhog.on('identify', (user) => {
analytics.identify(user.id, {
email: user.email,
name: user.name
});
});
// Submit
feedhog.on('submit', (feedback) => {
analytics.track('feedback_submitted', {
feedback_id: feedback.id,
feedback_type: feedback.type,
feedback_title: feedback.title
});
});
// Vote
feedhog.on('vote', ({ feedbackId, result }) => {
analytics.track(result.voted ? 'feedback_upvoted' : 'feedback_vote_removed', {
feedback_id: feedbackId,
vote_count: result.voteCount
});
});
// Error
feedhog.on('error', (error) => {
analytics.track('feedhog_error', {
error_message: error.message
});
});Global Error Handling
Set up a global error handler for all SDK operations:
import Feedhog, { FeedhogApiError } from '@feedhog/js';
const feedhog = new Feedhog({ apiKey: 'fhpk_your_public_key' });
feedhog.on('error', (error) => {
if (error instanceof FeedhogApiError) {
switch (error.status) {
case 401:
console.error('Authentication failed - check your API key');
break;
case 403:
console.error('Access denied');
break;
case 404:
console.error('Resource not found');
break;
case 429:
console.error('Rate limited - slow down requests');
break;
case 500:
console.error('Server error - try again later');
break;
default:
console.error('API error:', error.message);
}
if (error.details) {
console.error('Validation errors:', error.details.fieldErrors);
}
} else {
console.error('Unexpected error:', error);
}
});