CoursesEditorialized ecommerce experiencesSimple block: Accordion

Editorialized ecommerce experiences

Lesson
2

Simple block: Accordion

Log in to mark your progress for each Lesson and Task

An "accordion" block is useful to display content such as frequently asked questions or terms and conditions.

In the Studio, add an Accordion item with the following two groups to the Body field with the following text:

What's the best way to take care of Jesmonite?
To clean any Jesmonite products, wipe down with a non-abrasive damp cloth. We coat our products with a waterproof sealant, but please do not leave Jesmonite to soak.
Is Jesmonite safe to eat from?
Whilst Jesmonite is a non-toxic, environmentally friendly material, we don’t recommend eating off the products, but can be used to serve dry things like nuts or whole fruit or to protect surfaces from hot pots & plates.

Thankfully, HTML gives us details and summary tags to natively show and hide content. All we need to do is to render our Sanity content into the correct tags.

Take note also in the component below how the imported PortableText component handles the array of objects that field creates, and renders HTML.

Create a new file to your Hydrogen project
./app/components/AccordionBlock.tsx
import {PortableText} from '@portabletext/react';
import type {Accordion} from '~/sanity/sanity.types';
export function AccordionBlock(props: Accordion) {
return Array.isArray(props.groups) ? (
<div className="flex flex-col bg-blue-50 divide-y divide-blue-100">
{props.groups.map((group) => (
<details key={group._key} className="p-4 w-full max-w-lg mx-auto">
<summary className="font-bold py-2">{group.title}</summary>
{Array.isArray(group.body) ? (
<PortableText value={group.body} />
) : null}
</details>
))}
</div>
) : null;
}
Take note of how defensive coding practices check any value is not null before attempting to render it. This is especially useful when your front end leverages Visual Editing and you are viewing incomplete, draft documents.

To render this block, add it to the BLOCKS object back in the page route.

Update BLOCKS in the page route
./app/routes/$slug.tsx
import {AccordionBlock} from '~/components/AccordionBlock';
const BLOCKS: Record<string, (props: any) => JSX.Element | null> = {
accordion: AccordionBlock,
_unknown: (props: any) => <>{JSON.stringify(props)}</>,
};

You should now see styled, collapsible drop downs for the accordion block type in your Hydrogen project.

Now you've got a handle on taking an array of block content created in Sanity and rendering them in Hydrogen, let's take on something a little more advanced.

If your accordion is being used for FAQ's, and those FAQ's may be relevant in multiple locations – you should consider creating a dedicated faq document type and making this accordion block an array of references.