Widget Customization

Customize the appearance and behavior of the Feedhog feedback widget.

Widget Customization

The Feedhog widget can be customized to match your brand and integrate seamlessly with your application.

Appearance Options

Position

Control where the widget appears on the page:

// Script tag
window.feedhogSettings = {
  apiKey: 'fhpk_your_public_key',
  position: 'bottom-right' // bottom-right, bottom-left, top-right, top-left
};

// React
<FeedhogWidget
  apiKey="fhpk_your_public_key"
  position="bottom-left"
/>

Primary Color

Set your brand color for the trigger button and accent elements:

// Script tag
window.feedhogSettings = {
  apiKey: 'fhpk_your_public_key',
  primaryColor: '#8b5cf6' // Purple
};

// React
<FeedhogWidget
  apiKey="fhpk_your_public_key"
  primaryColor="#8b5cf6"
/>

Common brand colors:

  • #3b82f6 - Blue (default)
  • #8b5cf6 - Purple
  • #10b981 - Green
  • #f59e0b - Amber
  • #ef4444 - Red
  • #ec4899 - Pink
  • #06b6d4 - Cyan

Trigger Button Text

Customize the floating button label:

// Script tag
window.feedhogSettings = {
  apiKey: 'fhpk_your_public_key',
  triggerText: 'Share Ideas'
};

// React
<FeedhogWidget
  apiKey="fhpk_your_public_key"
  triggerText="Share Ideas"
/>

Ideas for trigger text:

  • "Feedback" (default)
  • "Share Ideas"
  • "Got Ideas?"
  • "Help Us Improve"
  • "Suggest a Feature"
  • "Report a Bug"

Customize the feedback modal's header:

// Script tag
window.feedhogSettings = {
  apiKey: 'fhpk_your_public_key',
  title: 'What would you like to see?',
  subtitle: 'Help us build better products for you'
};

// React
<FeedhogWidget
  apiKey="fhpk_your_public_key"
  title="What would you like to see?"
  subtitle="Help us build better products for you"
/>

Custom Trigger Button

Hide the default trigger and create your own:

Basic Custom Button

'use client';

import { FeedhogWidget } from '@feedhog/widget/react';

export function CustomFeedback() {
  return (
    <>
      <FeedhogWidget
        apiKey="fhpk_your_public_key"
        showTrigger={false}
      />

      <button
        onClick={() => window.FeedhogWidget?.open()}
        className="fixed bottom-4 right-4 bg-blue-500 text-white px-4 py-2 rounded-full shadow-lg hover:bg-blue-600"
      >
        💡 Have an idea?
      </button>
    </>
  );
}

Integration with UI Library

Using shadcn/ui:

'use client';

import { FeedhogWidget } from '@feedhog/widget/react';
import { Button } from '@/components/ui/button';
import { MessageSquarePlus } from 'lucide-react';

export function FeedbackTrigger() {
  return (
    <>
      <FeedhogWidget
        apiKey="fhpk_your_public_key"
        showTrigger={false}
      />

      <Button
        onClick={() => window.FeedhogWidget?.open()}
        className="fixed bottom-6 right-6"
        size="lg"
      >
        <MessageSquarePlus className="mr-2 h-5 w-5" />
        Share Feedback
      </Button>
    </>
  );
}

Multiple Trigger Locations

Add feedback triggers in different parts of your app:

'use client';

import { FeedhogWidget } from '@feedhog/widget/react';
import { Button } from '@/components/ui/button';

export function AppLayout({ children }: { children: React.ReactNode }) {
  return (
    <>
      <header className="flex justify-between p-4">
        <Logo />
        <nav>
          <Button
            variant="ghost"
            onClick={() => window.FeedhogWidget?.open()}
          >
            Feedback
          </Button>
        </nav>
      </header>

      <main>{children}</main>

      <footer className="p-4 text-center">
        <a
          href="#"
          onClick={(e) => {
            e.preventDefault();
            window.FeedhogWidget?.open();
          }}
        >
          Send us feedback
        </a>
      </footer>

      <FeedhogWidget
        apiKey="fhpk_your_public_key"
        showTrigger={false}
      />
    </>
  );
}

Context-Aware Trigger

Pre-fill context based on where the user clicked:

'use client';

import { FeedhogWidget } from '@feedhog/widget/react';

export function FeatureCard({ feature }: { feature: Feature }) {
  return (
    <div className="border rounded-lg p-4">
      <h3>{feature.title}</h3>
      <p>{feature.description}</p>

      <button
        onClick={() => {
          // Store context that could be captured
          sessionStorage.setItem('feedbackContext', JSON.stringify({
            feature: feature.id,
            page: window.location.pathname
          }));
          window.FeedhogWidget?.open();
        }}
      >
        Request changes
      </button>
    </div>
  );
}

Complete Configuration Examples

SaaS Dashboard

'use client';

import { FeedhogWidget } from '@feedhog/widget/react';
import { useAuth } from '@/hooks/use-auth';

export function DashboardFeedback() {
  const { user } = useAuth();

  return (
    <FeedhogWidget
      apiKey={process.env.NEXT_PUBLIC_FEEDHOG_API_KEY!}
      position="bottom-right"
      primaryColor="#6366f1" // Indigo to match dashboard
      triggerText="Feedback"
      title="How can we improve?"
      subtitle="Your feedback helps us build a better product"
      user={user ? {
        externalId: user.id,
        email: user.email,
        name: user.name,
        metadata: {
          plan: user.plan,
          accountId: user.accountId,
          role: user.role
        }
      } : undefined}
    />
  );
}

E-commerce

'use client';

import { FeedhogWidget } from '@feedhog/widget/react';
import { useCustomer } from '@/hooks/use-customer';

export function StoreFeedback() {
  const { customer } = useCustomer();

  return (
    <FeedhogWidget
      apiKey={process.env.NEXT_PUBLIC_FEEDHOG_API_KEY!}
      position="bottom-left"
      primaryColor="#059669" // Green for positive vibes
      triggerText="Help Us"
      title="Share your shopping experience"
      subtitle="We read every piece of feedback"
      user={customer ? {
        externalId: customer.id,
        email: customer.email,
        name: customer.firstName,
        metadata: {
          totalOrders: customer.orderCount,
          customerSince: customer.createdAt
        }
      } : undefined}
    />
  );
}

Developer Tool

'use client';

import { FeedhogWidget } from '@feedhog/widget/react';
import { useSession } from '@/hooks/use-session';

export function DevToolFeedback() {
  const { session } = useSession();

  return (
    <FeedhogWidget
      apiKey={process.env.NEXT_PUBLIC_FEEDHOG_API_KEY!}
      position="top-right"
      primaryColor="#f59e0b" // Amber for visibility
      triggerText="Report Issue"
      title="Found a bug or have a feature request?"
      subtitle="Help us make this tool better"
      user={session ? {
        externalId: session.userId,
        email: session.email,
        metadata: {
          plan: session.plan,
          apiVersion: session.apiVersion
        }
      } : undefined}
    />
  );
}

Shadow DOM Isolation

The widget uses Shadow DOM to prevent CSS conflicts:

  • Your site's CSS won't affect the widget
  • The widget's CSS won't affect your site
  • No need for CSS reset or scoping

This means:

  • Global styles won't break the widget
  • Tailwind/CSS frameworks work without conflicts
  • Dark mode toggles won't affect widget (it has its own theme)

Z-Index Considerations

The widget uses high z-index values to stay on top. If you have modals or overlays that should appear above the widget, you may need to adjust your z-index:

/* Example: Make your modal appear above the widget */
.my-modal {
  z-index: 10001; /* Widget uses ~10000 */
}

Accessibility

The widget is built with accessibility in mind:

  • Keyboard navigable (Tab, Enter, Escape)
  • ARIA labels on interactive elements
  • Focus management in modals
  • Screen reader announcements

To ensure good accessibility:

  1. Keep trigger text descriptive
  2. Don't hide the trigger unless you provide an accessible alternative
  3. Ensure custom triggers have proper ARIA attributes
<button
  onClick={() => window.FeedhogWidget?.open()}
  aria-label="Open feedback form"
>
  <FeedbackIcon />
</button>