# Faq-2

> A simple and professional FAQ section with categorized collapsible questions and answers

A shadcn/ui block from the [@hexui](https://hexui.sh) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/hexui/faq-2).

- Page, with a live preview: https://shadcn.exchange/r/hexui/faq-2
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/hexui/faq-2-light-d60de0e5694f8750.png
- Registry item: https://hexui.sh/r/faq-2.json
- Categories: faq
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://hexui.sh/r/faq-2.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `avatar`, `button`, `accordion`

## Files

### `registry/blocks/faq/faq-2/source/app/faq/page.tsx`

```tsx
import { FAQ } from "../../components/faq"

export default function Page() {
  return (
    <div className="flex min-h-screen w-full flex-col items-center px-6 py-4">
      <FAQ />
    </div>
  )
}
```

### `registry/blocks/faq/faq-2/source/components/faq.tsx`

```tsx
import {
  Accordion,
  AccordionContent,
  AccordionItem,
  AccordionTrigger,
} from "@/components/ui/accordion"
import { SupportContactCard, type SupportAvatar } from "./support-contact-card"

type FAQItem = {
  value: string
  question: string
  answer: string
}

// FAQs grouped by category; each category renders its own Accordion section.
type FAQCategory = {
  title: string
  items: FAQItem[]
}

const faqCategories: FAQCategory[] = [
  {
    title: "Account & Collaboration",
    items: [
      {
        value: "account",
        question: "How do I create an account?",
        answer:
          "You can sign up using your email address or a supported social login. Once registered, your workspace will be created automatically and you can start adding pages immediately.",
      },
      {
        value: "collaboration",
        question: "Can I collaborate with my team in real time?",
        answer:
          "Yes, multiple users can edit the same page simultaneously. Changes are synced instantly, and you can leave comments, mention teammates, and track updates in real time.",
      },
      {
        value: "offline",
        question: "Does the app work offline?",
        answer:
          "You can view and edit recently opened pages without an internet connection. Your changes will automatically sync once you reconnect.",
      },
    ],
  },
  {
    title: "Security & Data",
    items: [
      {
        value: "security",
        question: "How is my data secured?",
        answer:
          "All data is encrypted in transit and at rest. We follow industry-standard security practices and regularly perform backups to ensure your content is protected.",
      },
      {
        value: "storage",
        question: "Is there a storage limit?",
        answer:
          "Free plans include a limited storage quota, while paid plans offer higher or unlimited storage depending on the subscription tier.",
      },
    ],
  },
  {
    title: "Billing",
    items: [
      {
        value: "billing",
        question: "How does billing work?",
        answer:
          "Billing is based on your selected plan and the number of active users in your workspace. You can upgrade, downgrade, or cancel your subscription at any time from the billing settings.",
      },
    ],
  },
]

// Support team avatars; `className` z-indexes control their overlap order in AvatarGroup.
const supportAvatars: ReadonlyArray<SupportAvatar> = [
  {
    src: "/demo/avatars/avatar-1.svg",
    alt: "@u1",
    fallback: "A1",
    className: "z-1",
  },
  {
    src: "https://avatars.githubusercontent.com/u/114809507",
    alt: "@ri0n_dev",
    fallback: "RI",
    className: "z-2",
  },
  {
    src: "/demo/avatars/avatar-4.svg",
    alt: "@u2",
    fallback: "A4",
    className: "z-1",
  },
]

export function FAQ() {
  return (
    <section className="relative flex w-full justify-center py-16">
      <div className="flex w-full max-w-3xl flex-col items-center gap-10">
        <div className="flex flex-col gap-2 text-center">
          <p className="text-pretty text-sm leading-relaxed text-muted-foreground">
            FAQ
          </p>
          <h1 className="text-balance text-2xl font-semibold tracking-tight md:text-3xl xl:text-4xl">
            Your Questions Answered
          </h1>
          <p className="mt-2 text-muted-foreground">
            Need help with something? Here are some of the most common questions
            we get.
          </p>
        </div>

        <div className="flex w-full max-w-2xl flex-col gap-8">
          {faqCategories.map((category) => (
            <div key={category.title} className="flex flex-col gap-2">
              <h2 className="text-sm font-semibold tracking-wide text-foreground/80 md:text-base">
                {category.title}
              </h2>
              <Accordion>
                {category.items.map((item) => (
                  <AccordionItem key={item.value} value={item.value}>
                    <AccordionTrigger className="md:text-base">
                      {item.question}
                    </AccordionTrigger>
                    <AccordionContent className="md:text-base leading-relaxed text-muted-foreground/90">
                      {item.answer}
                    </AccordionContent>
                  </AccordionItem>
                ))}
              </Accordion>
            </div>
          ))}
        </div>

        <SupportContactCard supportAvatars={supportAvatars} />
      </div>
    </section>
  )
}
```

### `registry/blocks/faq/faq-2/source/components/support-contact-card.tsx`

```tsx
import {
  Avatar,
  AvatarFallback,
  AvatarGroup,
  AvatarImage,
} from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"

export type SupportAvatar = {
  src: string
  alt: string
  fallback: string
  className: string
}

type SupportContactCardProps = {
  supportAvatars: ReadonlyArray<SupportAvatar>
}

export function SupportContactCard({ supportAvatars }: SupportContactCardProps) {
  return (
    <div className="flex w-full flex-col items-center rounded-lg border px-4 py-14">
      <div className="flex max-w-lg flex-col items-center gap-5">
        {/* `grayscale` mutes the avatars so the CTA button remains the visual focus. */}
        <AvatarGroup className="grayscale">
          {supportAvatars.map((avatar) => (
            <Avatar
              key={avatar.src}
              size="lg"
              className={cn("border bg-accent", avatar.className)}
            >
              <AvatarImage src={avatar.src} alt={avatar.alt} />
              <AvatarFallback>{avatar.fallback}</AvatarFallback>
            </Avatar>
          ))}
        </AvatarGroup>
        <div className="flex flex-col gap-2 text-center">
          <h2 className="font-semibold md:text-2xl">Still have questions?</h2>
          <p className="text-muted-foreground">
            If you can&rsquo;t find the answer you&rsquo;re looking for, please
            chat to our support team.
          </p>
        </div>
        <Button size="lg">Get in touch</Button>
      </div>
    </div>
  )
}
```
