Blocks

Frequently Asked Questions

The Frequently Asked Questions (FAQ) block can be used to show commonly asked questions and answers from your users. It has title and text fields and uses entries as a way to write a faq once and reuse it in different FAQ blocks all across your site.

Front End

The answer is hidden until the user clicks on the + sign next to the question.

The answer will then be shown below the question and the + rotates to become a x.

Content Model

The content model for the FAQ block is as follows:

title: Text Field - Required

text: Text Field - Optional

faqs: Content Links Field - Required

The faqs links to faq entries that have the following content model:

Code

The FAQ block uses the ContentLinks and BlockData types from the Contento JavaScript SDK. It also uses the classNames utility function for dynamic css.

The FAQ function uses Reacts useState to store an FAQ items active state to show and hide the question and rotate state for the + icon rotation.

import { ContentLinks } from '@/types/types'
import { classNames } from '@/utils/ClassNames'
import { BlockData } from '@gocontento/client'
import { useState } from 'react'

export default function FAQs({ block }: { block: BlockData }) {
  return (
    <div className="py-9 md:py-16">
      <div className="prose mx-auto">
        <h2 className="text-center text-3xl font-semibold md:text-5xl">
          {block.fields.title.text}
        </h2>
        <p className="text-center">{block.fields.text?.text}</p>
      </div>
      <div className="mx-auto my-9 max-w-[1000px]">
        {block.fields.faqs.content_links[0] &&
          block.fields.faqs.content_links.map((item: ContentLinks) => {
            return (
              <FAQ item={item} key={item.content_link.fields.question.text} />
            )
          })}
      </div>
    </div>
  )
}

function FAQ({ item }: { item: ContentLinks }) {
  const [active, setActive] = useState(false)
  const [rotate, setRotate] = useState(false)

  function toggleAccordion() {
    setActive((prevState) => !prevState)
    setRotate((prevState) => !prevState)
  }
  return (
    <div className="w-full border-b border-b-black">
      <div
        className="flex cursor-pointer items-center justify-between gap-x-10 py-8"
        onClick={toggleAccordion}
      >
        <h3 className="text-2xl font-semibold lg:text-3xl">
          {item.content_link.fields.question.text}
        </h3>
        <span
          className={classNames(
            'text-3xl',
            rotate ? 'rotate-45 transform' : '',
          )}
        >
          +
        </span>
      </div>
      <div
        className={classNames(
          'max-w-none pb-9 text-lg',
          active ? 'block' : 'hidden',
        )}
        dangerouslySetInnerHTML={{
          __html: item.content_link.fields.answer.text,
        }}
      />
    </div>
  )
}
Hollie Duncan

Written by Hollie Duncan

Updated

Previous
Contact Form