React Installation
Learn how to integrate FeedbackJar into your React application.
Basic Installation
Option 1: Script Tag (Recommended)
Add the script to your public/index.html:
html
<script src="https://cdn.feedbackjar.com/sdk.js"></script>
<script>
window.fj.init('YOUR_WIDGET_ID');
</script> Option 2: React Hook
Create a custom hook to manage FeedbackJar:
tsx
import { useEffect } from 'react';
export function useFeedbackJar(widgetId: string) {
useEffect(() => {
// Load SDK
const script = document.createElement('script');
script.src = 'https://cdn.feedbackjar.com/sdk.js';
script.async = true;
document.body.appendChild(script);
script.onload = () => {
window.fj.init(widgetId);
};
return () => {
// Cleanup
if (window.fj) {
window.fj.destroy();
}
};
}, [widgetId]);
} Then use it in your App component:
tsx
import { useFeedbackJar } from './hooks/useFeedbackJar';
function App() {
useFeedbackJar('YOUR_WIDGET_ID');
return <div>Your app content</div>;
} User Identification
Fetch a signed payload from your backend (see Auto-login), then call identify. Unsigned id/email only personalizes the widget — posts stay guests. Full details: User Identification.
tsx
import { useEffect } from 'react';
function App() {
const user = useAuth(); // Your auth hook
const identifyPayload = useFeedbackJarIdentifyPayload(); // from your API
useEffect(() => {
if (!window.fj) return;
if (!user) {
window.fj.identify(null);
return;
}
if (identifyPayload?.signature) {
window.fj.identify(identifyPayload);
}
}, [user, identifyPayload]);
return <div>Your app content</div>;
} Custom Trigger
Hide the default button and use your own:
tsx
function CustomFeedbackButton() {
const handleClick = () => {
window.fj.showWidget();
};
return (
<button onClick={handleClick}>
Share Feedback
</button>
);
} Initialize with custom trigger:
tsx
window.fj.init('YOUR_WIDGET_ID', {
trigger: 'custom'
}); TypeScript Support
Add type definitions:
typescript
declare global {
interface Window {
fj: {
init: (widgetId: string, options?: Record<string, unknown>) => void;
identify: (user: Record<string, unknown> | null) => void;
showWidget: (options?: Record<string, unknown>) => void;
hideWidget: () => void;
destroy: () => void;
setTheme: (theme: 'auto' | 'light' | 'dark') => void;
setWidgetPosition: (position: 'left' | 'right') => void;
setWidgetEnabled: (enabled: boolean) => void;
getWidgetState: () => Promise<{
isOpen: boolean;
section: string;
}>;
};
$fjq: [string, ...unknown[]][];
}
}