Next.js SDK — React Hooks & SSR Helpers
Next.js integration for TheFAQApp via @faqapp/nextjs. React hooks, components, SSR/SSG helpers, and SEO utilities for FAQ content.
Next.js SDK (@faqapp/nextjs)
React hooks, components, SSR/SSG helpers, and SEO utilities for Next.js.
Re-exports everything from @faqapp/core, so you only need one package.
View on npm → · Core SDK on npm →
Install
npm install @faqapp/nextjsHooks
useFaq — List & Filter Questions
'use client';
import { useFaq } from '@faqapp/nextjs';
export function FAQList() {
const { data, loading, error, updateFilters } = useFaq({
config: {
apiKey: process.env.NEXT_PUBLIC_FAQ_API_KEY!,
organizationSlug: 'my-org',
},
initialFilters: { limit: 10, category: 'getting-started' },
});
if (loading) return <div>Loading...</div>;
return (
<div>
<input onChange={e => updateFilters({ search: e.target.value })} />
{data.questions.map(q => (
<article key={q.id}>
<h3>{q.question}</h3>
<div dangerouslySetInnerHTML={{ __html: q.answer }} />
</article>
))}
</div>
);
}Returns: { data, loading, error, refetch, updateFilters, filters }
data.questions—Question[]data.pagination—{ page, limit, total, pages } | nulldata.totalPages—number
useQuestion — Single Question with Feedback
'use client';
import { useQuestion } from '@faqapp/nextjs';
export function QuestionPage({ slug }: { slug: string }) {
const { data, loading, submitFeedback } = useQuestion({
config: { apiKey: '...', organizationSlug: 'my-org' },
questionSlug: slug,
});
if (loading || !data.question) return null;
return (
<div>
<h1>{data.question.question}</h1>
<div dangerouslySetInnerHTML={{ __html: data.question.answer }} />
<button onClick={() => submitFeedback({ helpful: true })}>👍</button>
<button onClick={() => submitFeedback({ helpful: false })}>👎</button>
</div>
);
}Returns: { data, loading, error, refetch, submitFeedback }
data.question—QuestionDetail | nullsubmitFeedback(params)— Submit helpful/not-helpful feedback
useSearch — Search Questions
'use client';
import { useSearch } from '@faqapp/nextjs';
export function SearchBar() {
const { data, loading, search } = useSearch({
config: { apiKey: '...', organizationSlug: 'my-org' },
});
return (
<div>
<input onChange={e => search(e.target.value)} placeholder="Search FAQ..." />
{data?.results.map(q => (
<a key={q.id} href={`/faq/${q.slug}`}>{q.question}</a>
))}
</div>
);
}Returns: { data, loading, error, search }
data—SearchResponse | nullwithresults,query, andtotalsearch(query, filters?)— Trigger a search
Server Components
Use @faqapp/core directly in Server Components (re-exported from @faqapp/nextjs):
import { FAQClient } from '@faqapp/nextjs';
export default async function FAQPage() {
const client = new FAQClient({
apiKey: process.env.FAQ_API_KEY!,
organizationSlug: 'my-org',
});
const page = await client.questions.list({ limit: 50 });
return (
<ul>
{page.data.map(q => <li key={q.id}>{q.question}</li>)}
</ul>
);
}Pre-built Components
<FaqList />
Full FAQ list with search and category filtering. Accepts data as props — fetch on the server and pass down.
import { FaqList } from '@faqapp/nextjs';
<FaqList
questions={questions}
categories={categories}
showCategories
searchable
onQuestionClick={(q) => router.push(`/faq/${q.slug}`)}
/>Props:
| Prop | Type | Default | Description |
|---|---|---|---|
questions | Question[] | required | Questions to display |
categories | Category[] | [] | Categories for grouping/filtering |
showCategories | boolean | true | Show category grouping |
searchable | boolean | true | Show search input |
onQuestionClick | (q: Question) => void | — | Click handler |
renderQuestion | (q: Question) => ReactNode | — | Custom question renderer |
renderCategory | (c: Category) => ReactNode | — | Custom category renderer |
<QuestionDetailComponent />
Question view with feedback buttons and related questions.
import { QuestionDetailComponent } from '@faqapp/nextjs';
<QuestionDetailComponent
question={questionDetail}
relatedQuestions={related}
showFeedback
onFeedbackSubmit={async (feedback) => {
await client.feedback.submit(slug, feedback);
}}
/>Props:
| Prop | Type | Default | Description |
|---|---|---|---|
question | QuestionDetail | required | Question to display |
relatedQuestions | Question[] | [] | Related questions |
showFeedback | boolean | true | Show feedback buttons |
showRelated | boolean | true | Show related questions |
onFeedbackSubmit | (feedback) => Promise<void> | — | Feedback handler |
SEO Utilities
FAQ Structured Data (JSON-LD)
import { generateFaqJsonLd, generateFaqSeoData } from '@faqapp/nextjs';
// Simple JSON-LD from questions array
const jsonLd = generateFaqJsonLd(questions, { name: 'My FAQ', url: 'https://example.com/faq' });
// Full SEO data with organization context
const seoData = generateFaqSeoData({
organization,
questions,
baseUrl: 'https://example.com',
currentPath: '/faq',
});
// Returns: { title, description, canonical, openGraph, jsonLd }Question Structured Data
import { generateQuestionSeoData } from '@faqapp/nextjs';
const seoData = generateQuestionSeoData({
organization,
question,
baseUrl: 'https://example.com',
currentPath: `/faq/${question.slug}`,
});Sitemap Generation
import { generateFaqSitemap, generateSitemapXml } from '@faqapp/nextjs';
const entries = generateFaqSitemap({
questions,
categories,
baseUrl: 'https://example.com',
basePath: '/faq',
});
const xml = generateSitemapXml(entries);Static Generation Helpers
Helpers for getStaticProps and getStaticPaths patterns:
import {
getFaqStaticProps,
getQuestionStaticProps,
getAllQuestionSlugs,
getAllCategorySlugs,
} from '@faqapp/nextjs';
// Get all question slugs for static paths
const slugs = await getAllQuestionSlugs({ config });
// Get props for FAQ listing page
const { props, revalidate } = await getFaqStaticProps({
config,
filters: { status: 'published' },
});
// Get props for a single question page
const { props } = await getQuestionStaticProps({
config,
questionSlug: 'how-to-reset',
});TypeScript SDK — Universal API Client
Official TypeScript SDK for TheFAQApp. Universal API client for Node.js, Deno, Bun, and the browser with full type safety and IntelliSense.
Authentication Guide — API Keys & Scopes
Learn how to authenticate with the TheFAQApp API using API keys. Covers key management, scopes, and secure authentication patterns.