React Installation

Learn how to integrate FeedbackJar into your React application.

Basic Installation

Add the script to your public/index.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:

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:

import { useFeedbackJar } from './hooks/useFeedbackJar';

function App() {
  useFeedbackJar('YOUR_WIDGET_ID');

  return <div>Your app content</div>;
}

User Identification

Identify logged-in users:

import { useEffect } from 'react';

function App() {
  const user = useAuth(); // Your auth hook

  useEffect(() => {
    if (user && window.fj) {
      window.fj.identify({
        id: user.id,
        email: user.email,
        firstName: user.firstName,
        lastName: user.lastName,
        avatar: user.avatar,
      });
    }
  }, [user]);

  return <div>Your app content</div>;
}

Custom Trigger

Hide the default button and use your own:

function CustomFeedbackButton() {
  const handleClick = () => {
    window.fj.showWidget();
  };

  return (
    <button onClick={handleClick}>
      Share Feedback
    </button>
  );
}

Initialize with custom trigger:

window.fj.init('YOUR_WIDGET_ID', {
  trigger: 'custom'
});

TypeScript Support

Add type definitions:

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[]][];
  }
}