Integrations

Next.js Integration

Complete guide to integrating FeedbackKit with Next.js applications using App Router, Pages Router, and server-side features.

React Hooks

Built-in hooks for seamless integration

Server Components

SSR and SSG support with optimizations

TypeScript

Full type safety and IntelliSense

Feedback Widget

Pre-built widget for rapid development

App Router

Modern routing with layouts and loading states

Performance

Optimized for Core Web Vitals

Installation & Setup

Install FeedbackKit

Add FeedbackKit to your Next.js project

# Install the widget package
npm install @feedbackkit/widget

# Install peer dependencies
npm install @feedbackkit/js

# For TypeScript support (recommended)
npm install -D @types/node

App Router Integration

Global Layout Setup

Add the feedback widget to your root layout for app-wide availability

// app/layout.tsx
import { FeedbackWidget } from '@feedbackkit/widget';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <FeedbackWidget 
          apiKey={process.env.NEXT_PUBLIC_FEEDBACKKIT_API_KEY!}
          appName="My App"
          trigger="floating"
          position="bottom-right"
        />
      </body>
    </html>
  );
}

Pages Router Integration

_app.tsx Setup

Add the feedback widget to your Pages Router app

// pages/_app.tsx
import type { AppProps } from 'next/app';
import { FeedbackWidget } from '@feedbackkit/widget';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Component {...pageProps} />
      <FeedbackWidget 
        apiKey={process.env.NEXT_PUBLIC_FEEDBACKKIT_API_KEY!}
        appName="My App"
        trigger="floating"
        position="bottom-right"
        theme={{
          primaryColor: "#ec4899",
          borderRadius: "8px"
        }}
      />
    </>
  );
}

API Routes

Server-Side Feedback Processing

Create API routes to process feedback server-side

// pages/api/feedback.ts
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'POST') {
    return res.status(405).json({ message: 'Method not allowed' });
  }

  try {
    const { type, priority, title, description, email, metadata } = req.body;

    // Forward to FeedbackKit API
    const response = await fetch('https://api.feedbackkit.io/feedback', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': process.env.FEEDBACKKIT_API_KEY!,
      },
      body: JSON.stringify({
        type,
        priority,
        title,
        description,
        email,
        metadata: {
          ...metadata,
          source: 'nextjs-api-route',
          timestamp: new Date().toISOString(),
        },
      }),
    });

    if (!response.ok) {
      throw new Error('Failed to submit feedback');
    }

    const result = await response.json();

    // Optional: Send notifications
    await sendSlackNotification(result);
    await sendEmailNotification(result);

    res.status(200).json(result);
  } catch (error) {
    console.error('Feedback submission error:', error);
    res.status(500).json({ message: 'Internal server error' });
  }
}

async function sendSlackNotification(feedback: any) {
  // Implementation for Slack notification
}

async function sendEmailNotification(feedback: any) {
  // Implementation for email notification
}

Performance Optimization

Dynamic Imports

// Lazy load the feedback widget
import dynamic from 'next/dynamic';

const FeedbackWidget = dynamic(
  () => import('@feedbackkit/widget').then(mod => ({ default: mod.FeedbackWidget })),
  {
    ssr: false,
    loading: () => <div>Loading feedback widget...</div>
  }
);

export default function MyPage() {
  return (
    <div>
      <h1>My Page</h1>
      <FeedbackWidget 
        apiKey={process.env.NEXT_PUBLIC_FEEDBACKKIT_API_KEY!}
        appName="My App"
      />
    </div>
  );
}

Conditional Loading

// Only load widget on client side
'use client';

import { useEffect, useState } from 'react';
import { FeedbackWidget } from '@feedbackkit/widget';

export default function MyPage() {
  const [isClient, setIsClient] = useState(false);

  useEffect(() => {
    setIsClient(true);
  }, []);

  return (
    <div>
      <h1>My Page</h1>
      {isClient && (
        <FeedbackWidget 
          apiKey={process.env.NEXT_PUBLIC_FEEDBACKKIT_API_KEY!}
          appName="My App"
        />
      )}
    </div>
  );
}

Best Practices

Environment Variables

Use NEXT_PUBLIC_ prefix

Always prefix client-side environment variables with NEXT_PUBLIC_

Type Safety

Define environment variable types for better TypeScript support

Validation

Validate environment variables at build time

Server Components

Client Boundaries

Use 'use client' directive only when necessary

Hydration

Handle hydration mismatches with proper client-side checks

Performance

Lazy load widgets to improve initial page load