Skip to content

FAQAccordion

The FAQAccordion component displays frequently asked questions in an interactive, collapsible accordion format.

  • Type: Content Component
  • Category: Interactive Content
  • Complexity: Moderate
  • File: src/components/FAQAccordion.astro
  • Collapsible Sections - Click to expand/collapse answers
  • Category Filtering - Show FAQs by category
  • Configuration-Driven - Content from faqData.ts
  • SEO-Friendly - Proper heading structure
  • Keyboard Accessible - Full keyboard navigation support
  • Smooth Animations - Transitions when expanding/collapsing
interface Props {
faqs?: FAQItem[];
category?: string;
}
PropTypeDefaultDescription
faqsFAQItem[]All FAQs from configArray of FAQ items to display
categorystringundefinedFilter FAQs by category
interface FAQItem {
question: string;
answer: string;
category?: string;
}
---
import FAQAccordion from '@/components/FAQAccordion.astro';
---
<FAQAccordion />

FAQs are defined in src/data/faqData.ts:

src/data/faqData.ts
export interface FAQItem {
question: string;
answer: string;
category?: string;
}
export const faqData: FAQItem[] = [
{
question: 'What is FiNAN?',
answer: 'FiNAN (Filipino Nurses Association in the Nordic Region) is a non-profit organization connecting Filipino nurses across the Nordic countries.',
category: 'general',
},
{
question: 'How can I join FiNAN?',
answer: 'Visit our membership page and complete the online application form. Membership is open to all Filipino nurses working in the Nordic region.',
category: 'membership',
},
// ... more FAQs
];
  1. Open the FAQ data file

    Navigate to: src/data/faqData.ts

  2. Add a new FAQ object

    {
    question: 'Your question here?',
    answer: 'Your detailed answer here.',
    category: 'general', // or 'membership', 'events', etc.
    },
  3. Choose a category (optional but recommended)

    Common categories:

    • general - About FiNAN
    • membership - Joining and member benefits
    • events - Event-related questions
    • contact - How to reach us
  4. Build and test

    Terminal window
    pnpm build
  5. Verify on FAQ page

    Check that your FAQ appears at /faq

The accordion uses JavaScript for interactivity:

<script is:inline src="/js/faq-accordion.js" defer></script>

Features:

  • Click to toggle - Open/close individual items
  • Auto-close others - Optional: close other items when opening one
  • Smooth transitions - CSS transitions for expand/collapse
  • ARIA attributes - Proper aria-expanded states
/* Closed state */
.faq-item { }
/* Open state */
.faq-item.active {
/* Answer visible */
}
/* Icon rotation */
.faq-icon {
transition: transform 0.3s;
}
.faq-item.active .faq-icon {
transform: rotate(180deg);
}
  • Container: Max-width with padding
  • Items: Stacked vertically with borders
  • Spacing: Consistent gaps between items
  • Question: Bold, larger text (lg or xl)
  • Answer: Regular weight, comfortable line height
  • Color: Dark text on white background
  • Hover State: Subtle background color change
  • Focus State: Visible outline for keyboard users
  • Icon: Chevron or plus/minus that rotates when open

Organize FAQs by category for better user experience:

  1. General - About the organization
  2. Membership - How to join, benefits, fees
  3. Events - Event information, registration
  4. Contact - How to reach representatives
  5. Resources - Guides, documents, links

Display category-specific FAQs on different pages:

<!-- On membership page -->
<FAQAccordion category="membership" />
<!-- On events page -->
<FAQAccordion category="events" />
<!-- On general FAQ page (all categories) -->
<FAQAccordion />
  • Keyboard Navigation: Tab through questions, Enter/Space to toggle
  • ARIA Labels:
    • aria-expanded="true|false" on buttons
    • aria-controls linking button to content
  • Semantic HTML:
    • <h3> or <h4> for questions
    • <button> for interactive triggers
  • Focus Management: Visible focus indicators

Combine with the StructuredData component for rich snippets:

---
import FAQAccordion from '@/components/FAQAccordion.astro';
import StructuredData from '@/components/StructuredData.astro';
import { faqData } from '@/data/faqData';
---
<!-- FAQ Page with structured data -->
<StructuredData type="FAQPage" data={faqData} />
<FAQAccordion />

This creates FAQ rich snippets in Google search results.

  • Answers user questions directly
  • Reduces support inquiries
  • Improves search rankings for question keywords
  • Increases time on page

Keep all items closed by default:

// In faq-accordion.js
const defaultOpen = false; // Change from true

Allow multiple items open:

// In faq-accordion.js
const allowMultiple = true; // Change from false

Change icon:

<!-- Replace chevron with plus/minus -->
<svg class="faq-icon">
<path d="M12 5v14M5 12h14" /> <!-- Plus icon -->
</svg>

Add answer formatting:

<div class="faq-answer" set:html={faq.answer} />

This allows HTML in answers (use carefully).

Do:

  • Keep questions concise (one sentence)
  • Provide complete, helpful answers (2-4 sentences)
  • Use categories to organize related questions
  • Update FAQs based on common user questions
  • Include links in answers when relevant

Don’t:

  • Create overly long answers (consider a dedicated page instead)
  • Use technical jargon without explanation
  • Duplicate information across multiple FAQs
  • Leave outdated information

Cause: Typo in category name

Solution: Verify category matches exactly:

<FAQAccordion category="membership" /> // Must match data exactly

Cause: JavaScript file not loading

Solution: Check that /js/faq-accordion.js exists and loads properly

Cause: Invalid JSON in faqData.ts

Solution: Ensure proper TypeScript syntax with commas and quotes

  • Lazy Script Loading: Uses defer attribute
  • No Heavy Dependencies: Pure JavaScript
  • CSS Animations: Hardware-accelerated transforms
  • Static Content: FAQ content is static, loads fast
  • faqData.ts - FAQ content configuration
  • public/js/faq-accordion.js - Interactive functionality
  • FAQ Page (/faq) - Primary usage
  • Membership Page - Membership-specific FAQs
  • Event Pages - Event-specific questions

View the complete implementation:

https://github.com/poncardasm/finan-website/blob/main/src/components/FAQAccordion.astro
https://github.com/poncardasm/finan-website/blob/main/src/data/faqData.ts
https://github.com/poncardasm/finan-website/blob/main/public/js/faq-accordion.js