DEV Community

Brian Keary
Brian Keary

Posted on • Originally published at bkthemes.design on

How to Add an Interactive FAQ Accordion to Your Astro Blog: A Step-by-Step Guide

Introduction

Let’s build an Interactive FAQ Accordion for Astro. Modern web users expect interactive, accessible, and visually appealing content. One of the most effective ways to present frequently asked questions (FAQs) is with an accordion component—an interface element that allows users to expand and collapse answers as needed. In this article, we’ll walk through the entire process of adding a dynamic FAQ accordion to an Astro blog, from planning and implementation to troubleshooting and SEO optimization.

1. Planning the FAQ Feature

Before writing any code, it’s important to clarify your goals and requirements:

  • User Experience: The accordion should be easy to use, accessible, and visually consistent with your site.
  • Content Management: FAQ data should be easy to update, ideally stored in your markdown frontmatter.
  • SEO: The FAQ should be marked up with structured data (FAQPage schema) for rich search results.
  • Performance: The component should only load client-side JavaScript when needed.

2. Structuring FAQ Data in Markdown

Astro’s content collections allow you to store blog posts as markdown files with YAML frontmatter. To make your FAQ dynamic, add an array of question/answer objects to the frontmatter:

---
title: "How to Add an Accordion to Astro"
description: "A step-by-step guide to adding an interactive FAQ accordion to your Astro blog."
faq:
  - title: "What is an accordion?"
    content: "An accordion is a UI component that expands to reveal hidden content."
  - title: "Why use an accordion for FAQs?"
    content: "It keeps the page tidy and lets users focus on the questions they care about."
---

Enter fullscreen mode Exit fullscreen mode

This approach keeps your content and logic separate, making it easy to update FAQs without touching code.

3. Creating the Accordion Component

Astro supports multiple frameworks for interactive components. For maximum compatibility and interactivity, we’ll use React. First, ensure you have the React integration:

npx astro add react

Enter fullscreen mode Exit fullscreen mode

Then, create a new file src/components/Accordion.jsx:

import React, { useState } from 'react';
import './Accordion.css';

export default function Accordion({ items = [] }) {
  const [openIndex, setOpenIndex] = useState(-1);

  const toggle = (index) => {
    setOpenIndex(openIndex === index ? -1 : index);
  };

  return (
    <div className="accordion">
      {items.map((item, i) => (
        <div className="accordion-item" key={i}>
          <div className="accordion-header" onClick={() => toggle(i)}>
            {item.title}
          </div>
          <div className={`accordion-panel${openIndex === i ? ' open' : ''}`}> 
            {item.content}
          </div>
        </div>
      ))}
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

4. Styling the Accordion

Create a CSS file src/components/Accordion.css:

.accordion {
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #ddd;
}
.accordion-item + .accordion-item {
  border-top: 1px solid #ddd;
}
.accordion-header {
  background: #f7f7f7;
  cursor: pointer;
  padding: 1em;
  font-weight: bold;
  transition: background 0.2s;
}
.accordion-header:hover {
  background: #eaeaea;
}
.accordion-panel {
  padding: 1em;
  background: #fff;
  display: none;
}
.accordion-panel.open {
  display: block;
}

Enter fullscreen mode Exit fullscreen mode

5. Passing FAQ Data to the Accordion

In your Astro blog post page (e.g., src/pages/blog/[...slug].astro), import the Accordion and pass the FAQ data from the frontmatter:

---
import Accordion from '../../components/Accordion.jsx';
import '../../components/Accordion.css';
const { post } = Astro.props;
---

<main>
  <h1>{post.data.title}</h1>
  <article>
    <Content />
    {post.data.faq && <Accordion items={post.data.faq} client:load />}
  </article>
</main>

Enter fullscreen mode Exit fullscreen mode

The client:load directive ensures the React component hydrates on the client, enabling interactivity.

6. Troubleshooting Common Issues

a. React Integration Not Found:

If you see an error like “No valid renderer was found for the .jsx file extension,” make sure you’ve run npx astro add react and that your astro.config.mjs includes react() in the integrations array.

b. Dependency Conflicts:

If you get npm errors about React versions, ensure you’re using React 18 (not 19+) as of Astro v5. Example:

npm install react@18.2.0 react-dom@18.2.0

Enter fullscreen mode Exit fullscreen mode

c. FAQ Not Showing:

Check that your content collection schema in src/content.config.ts includes the faq field:

faq: z.array(z.object({
  title: z.string(),
  content: z.string()
})).optional(),

Enter fullscreen mode Exit fullscreen mode

d. Syntax Errors:

All JavaScript/TypeScript code in .astro files must be inside the frontmatter block (between --- lines).

7. Enhancing SEO with FAQ Schema

To help search engines understand your FAQ and potentially show rich results, add FAQPage structured data. In your BlogPostingJSONLD.astro component, generate a FAQPage schema if FAQ data exists:

---
const { faq = [] } = Astro.props;
const faqSchema = faq.length > 0 ? {
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": faq.map(q => ({
    "@type": "Question",
    "name": q.title,
    "acceptedAnswer": {
      "@type": "Answer",
      "text": q.content
    }
  }))
} : null;
---
{faqSchema && <script type="application/ld+json" set:html={JSON.stringify(faqSchema)} />}

Enter fullscreen mode Exit fullscreen mode

This outputs valid JSON-LD for Google and other search engines.

8. Accessibility and Best Practices

  • Use semantic HTML for headers and content.
  • Ensure keyboard navigation works (e.g., allow Enter/Space to toggle).
  • Add ARIA attributes for screen readers if needed.

9. Final Testing

  • Local Testing: Run npm run dev and verify the accordion works and FAQ data appears.
  • SEO Testing: Use Google’s Rich Results Test to validate your FAQPage schema.
  • Cross-Browser: Check the accordion in multiple browsers and on mobile.

Conclusion

Adding an interactive FAQ accordion to your Astro blog is a powerful way to improve user experience and SEO. By storing FAQ data in markdown frontmatter, using a React component for interactivity, and outputting FAQPage schema, you ensure your content is both user-friendly and search-engine-optimized. With this approach, you can easily add, update, or remove FAQs as your content evolves—no code changes required.

If you follow these steps, you’ll have a robust, maintainable, and SEO-friendly FAQ section that delights your readers and helps your site stand out in search results.

Top comments (0)