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/nodeApp 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