React accordion component for collapsible content sections. Built with TypeScript and Tailwind CSS for Next.js with keyboard navigation support.
Ever built a FAQ page where users had to scroll through walls of text to find one answer? Yeah, that's painful for everyone involved. This shadcn/ui accordion component solves that problem by letting users focus on what they actually need in your Next.js app—no scrolling through irrelevant content, no overwhelming walls of text.
Standard accordion for frequently asked questions:
Loading component...
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "~/components/ui/accordion"export default function AccordionDemo() { return ( <div className="w-full p-6 flex justify-center"> <div className="w-full max-w-lg"> <Accordion className="w-full" collapsible defaultValue="item-1" type="single"> <AccordionItem value="item-1"> <AccordionTrigger>Product Information</AccordionTrigger> <AccordionContent className="flex flex-col gap-4 text-balance"> <p> Our flagship product combines cutting-edge technology with sleek design. Built with premium materials, it offers unparalleled performance and reliability. </p> <p> Key features include advanced processing capabilities, and an intuitive user interface designed for both beginners and experts. </p> </AccordionContent> </AccordionItem> <AccordionItem value="item-2"> <AccordionTrigger>Shipping Details</AccordionTrigger> <AccordionContent className="flex flex-col gap-4 text-balance"> <p> We offer worldwide shipping through trusted courier partners. Standard delivery takes 3-5 business days, while express shipping ensures delivery within 1-2 business days. </p> <p> All orders are carefully packaged and fully insured. Track your shipment in real-time through our dedicated tracking portal. </p> </AccordionContent> </AccordionItem> <AccordionItem value="item-3"> <AccordionTrigger>Return Policy</AccordionTrigger> <AccordionContent className="flex flex-col gap-4 text-balance"> <p> We stand behind our products with a comprehensive 30-day return policy. If you're not completely satisfied, simply return the item in its original condition. </p> <p> Our hassle-free return process includes free return shipping and full refunds processed within 48 hours of receiving the returned item. </p> </AccordionContent> </AccordionItem> </Accordion> </div> </div> )}
The animations feel smooth, keyboard navigation works like you'd expect, and screen readers handle everything properly. Built with TypeScript for type safety and styled with Tailwind CSS classes.
Here's the thing—accordions aren't just about saving space. They're about respecting your users' attention. Instead of forcing someone to process everything at once, you let them choose what's relevant.
Think of it like a good table of contents—users scan headers, find what they need, and ignore the rest. That's smart information architecture that shadcn/ui components make effortless.
You can fit tons of content without making pages feel overwhelming. This becomes super important on mobile where every pixel matters.
Built on Radix UI primitives, this shadcn/ui component follows the WAI-ARIA accordion design pattern. Full keyboard navigation, screen reader support, and proper focus management work automatically. No extra JavaScript configuration needed.
Programmatically control which sections are open—useful for guided tours or linking to specific sections:
Loading component...
"use client"import { useState } from "react"import { Accordion, AccordionContent, AccordionItem, AccordionTrigger,} from "~/components/ui/accordion"import { Button } from "~/components/ui/button"export default function AccordionControlled() { const [value, setValue] = useState<string>("item-2") return ( <div className="w-full p-6 flex justify-center"> <div className="w-full max-w-lg space-y-4"> <div className="flex gap-2 flex-wrap"> <Button onClick={() => setValue("item-1")} size="sm" variant="outline"> Open First </Button> <Button onClick={() => setValue("item-2")} size="sm" variant="outline"> Open Second </Button> <Button onClick={() => setValue("item-3")} size="sm" variant="outline"> Open Third </Button> <Button onClick={() => setValue("")} size="sm" variant="outline"> Close All </Button> </div> <Accordion className="w-full" collapsible onValueChange={setValue} type="single" value={value} > <AccordionItem value="item-1"> <AccordionTrigger>Controlled Section 1</AccordionTrigger> <AccordionContent> This accordion is controlled programmatically. Use the buttons above to open specific sections, or click the triggers to change the value. The current value is:{" "} {value || "none"} </AccordionContent> </AccordionItem> <AccordionItem value="item-2"> <AccordionTrigger>Controlled Section 2</AccordionTrigger> <AccordionContent> Controlled accordions are useful when you need to synchronize the accordion state with other parts of your application, or when you want to open specific sections based on user actions elsewhere. </AccordionContent> </AccordionItem> <AccordionItem value="item-3"> <AccordionTrigger>Controlled Section 3</AccordionTrigger> <AccordionContent> You can also use controlled state to implement features like "expand all" or "collapse all", or to save and restore the accordion state from localStorage or a database. </AccordionContent> </AccordionItem> </Accordion> </div> </div> )}
Each pattern serves different use cases in your React applications. Whether you're building with Next.js or another framework, these accordion patterns handle the complex state management so you don't have to.
Performance matters. This free shadcn/ui component is lightweight and works great in TypeScript projects. The Tailwind CSS styling keeps bundle sizes small while maintaining full customization.
Default states create better UX. For FAQs, keep everything closed—let users choose what to open. For dashboards, consider opening the most important section by default. Similar to Tabs, think about which content users need first.
Trigger labels should be scannable. "Payment & Billing" beats "Manage your payment methods and billing preferences." Users need to scan quickly.
Test keyboard navigation thoroughly. Arrow keys should move between triggers, Space/Enter should toggle items. This open source shadcn/ui component handles focus management, but custom triggers need testing.
Radix UI foundation. This component wraps @radix-ui/react-accordion, giving you unstyled primitives with perfect accessibility. The shadcn/ui styling layer adds beautiful defaults while keeping full customization possible.
Accordions work great with Form components for organizing complex React interfaces. Combine with Badge components to show status or counts in trigger headers. Use Lucide React icons for visual hierarchy—the shadcn/ui design system makes these integrations smooth in JavaScript applications.