Code Examples
Complete integration examples for common frameworks and use cases.
Next.js App Router
Full integration with Next.js 14+ App Router and server components.
1. Create Support Provider
components/SupportProvider.tsxtsx
// components/SupportProvider.tsx
'use client'
import { SupportWidget } from '@supportflow/react'
import { useAuth } from '@/hooks/useAuth'
export function SupportProvider({ children }: { children: React.ReactNode }) {
const { user, isAuthenticated } = useAuth()
return (
<>
{children}
{isAuthenticated && user && (
<SupportWidget
appId={process.env.NEXT_PUBLIC_SUPPORTFLOW_APP_ID!}
user={{
id: user.id,
email: user.email,
name: user.name,
}}
token={user.supportToken}
/>
)}
</>
)
}2. Add to Root Layout
app/layout.tsxtsx
// app/layout.tsx
import { SupportProvider } from '@/components/SupportProvider'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<SupportProvider>
{children}
</SupportProvider>
</body>
</html>
)
}3. Generate Token in API Route
app/api/support-token/route.tstsx
// app/api/support-token/route.ts
import { NextResponse } from 'next/server'
import jwt from 'jsonwebtoken'
import { getServerSession } from 'next-auth'
export async function GET() {
const session = await getServerSession()
if (!session?.user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const token = jwt.sign(
{
sub: session.user.id,
email: session.user.email,
name: session.user.name,
},
process.env.SUPPORT_JWT_SECRET!,
{ expiresIn: '24h' }
)
return NextResponse.json({ token })
}React with REST API
Direct API integration without the widget.
Custom API Integrationtsx
// hooks/useSupportFlow.ts
import { useState, useEffect } from 'react'
const API_BASE = 'https://support.example.com/api/support/myapp'
export function useSupportFlow(token: string) {
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
}
async function searchArticles(query: string) {
const res = await fetch(
`${API_BASE}/articles?search=${encodeURIComponent(query)}`,
{ headers }
)
return res.json()
}
async function createIssue(data: {
title: string
description: string
type: 'bug' | 'feature' | 'billing' | 'other'
}) {
const res = await fetch(`${API_BASE}/issues`, {
method: 'POST',
headers,
body: JSON.stringify(data),
})
return res.json()
}
async function sendChatMessage(message: string, sessionId?: string) {
const res = await fetch(`${API_BASE}/chat`, {
method: 'POST',
headers,
body: JSON.stringify({ message, sessionId }),
})
return res.json()
}
return { searchArticles, createIssue, sendChatMessage }
}
// Usage in component
function HelpButton() {
const { searchArticles, sendChatMessage } = useSupportFlow(userToken)
const [answer, setAnswer] = useState('')
async function handleSearch(query: string) {
const { articles } = await searchArticles(query)
// Display articles
}
async function handleChat(message: string) {
const { message: response } = await sendChatMessage(message)
setAnswer(response.content)
}
return (/* ... */)
}Express.js Backend
Token generation endpoint for Express apps.
Express Token Routejavascript
// routes/support.js
import express from 'express'
import jwt from 'jsonwebtoken'
import { requireAuth } from '../middleware/auth'
const router = express.Router()
// Generate support token for authenticated users
router.get('/support-token', requireAuth, (req, res) => {
const token = jwt.sign(
{
sub: req.user.id,
email: req.user.email,
name: req.user.name,
},
process.env.SUPPORT_JWT_SECRET,
{ expiresIn: '24h' }
)
res.json({ token })
})
export default routerDjango Backend
Token generation for Django REST Framework.
Django Token Viewpython
# views.py
import jwt
import os
from datetime import datetime, timedelta
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
class SupportTokenView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request):
payload = {
'sub': str(request.user.id),
'email': request.user.email,
'name': request.user.get_full_name(),
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(hours=24)
}
token = jwt.encode(
payload,
os.environ['SUPPORT_JWT_SECRET'],
algorithm='HS256'
)
return Response({'token': token})
# urls.py
from django.urls import path
from .views import SupportTokenView
urlpatterns = [
path('api/support-token/', SupportTokenView.as_view()),
]Bug Report with State Capture
Capture browser state and create detailed bug reports.
Bug Report with State Capturetsx
// components/BugReportButton.tsx
'use client'
import { useState } from 'react'
import { useSupportFlow } from '@supportflow/react'
export function BugReportButton() {
const { createIssue } = useSupportFlow()
const [isSubmitting, setIsSubmitting] = useState(false)
async function handleBugReport() {
setIsSubmitting(true)
// Capture current state
const metadata = {
url: window.location.href,
userAgent: navigator.userAgent,
screenSize: `${window.innerWidth}x${window.innerHeight}`,
timestamp: new Date().toISOString(),
// Add custom app state
localStorage: Object.keys(localStorage),
}
// Capture console errors (if tracked)
const errors = window.__capturedErrors || []
try {
await createIssue({
title: 'Bug Report from App',
description: 'User-submitted bug report',
type: 'bug',
metadata,
attachments: errors.length > 0 ? [{
name: 'console-errors.json',
content: JSON.stringify(errors),
type: 'application/json'
}] : undefined
})
alert('Bug report submitted!')
} catch (error) {
console.error('Failed to submit bug report:', error)
} finally {
setIsSubmitting(false)
}
}
return (
<button
onClick={handleBugReport}
disabled={isSubmitting}
className="fixed bottom-4 left-4 bg-red-500 text-white px-4 py-2 rounded"
>
{isSubmitting ? 'Submitting...' : 'Report Bug'}
</button>
)
}