How to structure Storyblok spaces using Atomic Design
Storyblok is the first headless CMS that works for developers & marketers alike.
As a part of our live event Stories from the Blok, Alba Silvente presented how to setup Storyblok space according to the Atomic Design methodology.
Demo live site: https://dawntraoz.github.io/atomic-design-storyblok
Demo open source repository: https://github.com/Dawntraoz/atomic-design-storyblok
Introduction
As a developer, it gets easier to structure code, and feel more comfortable making changes, as you gain experience with different projects.
When I start a coding project, I know that I am not the only one who will use it so my structure must fit all users.
This is where Atomic design comes into the picture. 💘
What is Storyblok?
Storyblok is a Headless CMS (Content Management System), the place where you will edit, add and delete your content. Instead of having a markdown file in your FrontEnd project, you will have a website where you will go and start writing content.
A Headless CMS is a back-end only content management system built as a content repository that makes content accessible via an API for display on any device. The term headless comes from the concept of chopping the “head” off the “body”, the “front“ off the “back“ .
What makes Storyblok stand apart from other Headless CMS is that it has a real-time Visual Editor. It provides developers with all the flexibility they need to build reliable and fast websites, while giving content creators with no coding skills the ability to edit content independently of the developer.
What is Atomic Design?
Atomic design is a methodology for creating design systems based on concepts in chemistry. There are five distinct levels to be aware of. They are as follows:
Atoms
This is the smallest unit that composes our application, it is not useful by itself but it allows you to have more control over the application elements.
An atom could be an input or a label, but to have a semantically correct field you would need the combination of both. They are not useful until you combine them at the next level.
Templates
Now, chemistry-based theory is set aside to return to the common web language.
Templates can be thought of as the skeleton of your page, made up of groups of organisms and/or molecules to form the common structure of a page.
You can have, for example, a template for the articles on your website (blog-post) and another for the sign forms (register).
This is a brief overview of how this methodology works, but if you want to know more details I recommend you read the book Atomic Design by Brad Frost
‘Atomic design is like mental model to help us think of our user interfaces as both a cohesive whole and a collection of parts at the same time’ - Brad Frost
- Control over the contentYou have more control over the content you and your team are creating, because you work with a methodology that makes you reuse the components you have created.
- Easily scaleIt's easy to scale your applications because you have reusable components in place.
- Align with all team membersIt's easy to align with designers and frontend teams because they already know about design systems and they will understand better how you are structuring your space.
- Single source of truthYou will generate a common language and a single source of truth by using the same methodology between teams, creating a design system.
- Improve reusabilityAs you are using reusable components, you will improve reusability, it will be easy to update your application or change the behavior/look'n'feel and you will have less components to fight with.
Now that we've outlined Storyblok's advantages, let's look at a real-world example! 🚀
Structuring our Storyblok space
Let's see how to create each level, which composes Atomic Design, in our Storyblok space and/or our FrontEnd project.
Atoms
This level is only part of our code.
In this case, the molecules are the components that fill the atoms through properties. So, the atoms don't need to be in our space, the molecules will do the work for them.
Although this methodology is applicable to any framework/library- for these examples I will use Vue.
Now imagine that we have created a Vue project; the next step is to go to the components folder and add a folder to store our atoms, called atoms.
One of our atoms could be Paragraph.vue, where we will create a <p>
html tag that will receive a property with the content.
Paragraph.vue
But obviously, an atom can have more than one property and have different styles. For example, in this component Heading.vue, we can apply different font styles for each type of tag: h1, h2, h3, ..., having the control of how it will be shown, wherever it is called.
Heading.vue
If you want to see more examples of atoms, here is the repository created for this demo https://github.com/Dawntraoz/atomic-design-storyblok/tree/main/components/atoms.
Molecules
This level will affect your code, creating a component that defines how to call the atoms, and the structure of your space, creating a component that awaits the content of the atoms.
Let's look at it more closely with a case study. We'll try to create a molecule that imitates this look and feel:
2. Create a new component
Click the New button, in the top right corner, and give your molecule a name, for example, heading-section, and leave it as Nestable, per default.
3. Define its properties
Once we have the component created, we can define the fields that the content creator will fill in and which we will receive in our code.
For this example we need two text type fields, named title and subtitle, and a textarea field, named intro.
In the Code
To create a molecule in our Vue project, we'll follow a process similar to the one we have done with atoms. First, create a folder called molecules and inside create a component called HeadingSection.vue, which will contain 2 Paragraph atoms and a Heading atom.
This time the component will receive the blok property, which is part of the response returned by the Storyblok API, and will contain the title, subtitle and intro properties already defined.
We only have to pass the content that comes from the API to the properties of each atom, as you can see below:
HeadingSection.vue
To see more molecules examples, check out this folder inside the repo: https://github.com/Dawntraoz/atomic-design-storyblok/tree/main/components/molecules
2. Create an organism.
Click the New button again and give your organism a name according to the name of the section. Because we are representing a number of services let's call it services and, again, leave it as Nestable.
3. Define its fields.
Once we have the molecules needed for this organism, we can define the fields that will expect a molecule as the content.
For this example, we need two blocks fields called heading, with a heading-section molecule, and services, with one or more service-card molecules.
Blocks fields allow you to add another component created in the Storyblok space as content, instead of adding a text or a link for example. Read more about them in the Storyblok developer guides.
To make it easier to understand let's see what the property heading contains. We can see, in the screenshot below, that the type of this field is blocks and it only allows heading-section components to be inserted. Actually, only 1, as specified by the maximum allowed.
In the Code
When it comes to creating an organism in our Vue project, it is even easier.
First, create a folder called organisms. Inside, create a component called Service.vue, which will contain 2 dynamic components. These dynamic components will be calling our molecules coming from the API response.
As you can see in the snippet below, this time the component will receive the blok property but, also, will fill in the blok property from the molecules.
The blok object will contain an array with only one item in heading, since we have set the maximum allowed to 1. But, in the case of services, we will have an array of 4 elements at most.
Each element of the arrays will contain the type of component (heading.component): heading-section.
Service.vue
To see other organisms in place, check out this other folder: https://github.com/Dawntraoz/atomic-design-storyblok/tree/main/components/organisms.
Content Types allow you to create templates for your content. Examples of common Content Types are blog-post, page. Read more about them in the Storyblok developer guides.
In Storyblok
We don't need a folder anymore, instead, we can create the template in the main folder All.
1. Create the template.
Go to the New button and give your template a name, according to the content it will receive. Since we are representing a common page in our application let's call it page-template. Then check Act as content type and exclude Nestable.
2. Define the body field.
Now that we have the molecules, which receive the content that will reach the atoms, and the organisms, which can already call the molecules they need, we need to create the template that calls those organisms.
To do this, we created a block type body field that will only allow us to call the components that are inside the organisms folder. In this way, we achieve a maximum of three levels of nesting depth in our panel of contents (page > organism > molecule).
In the Code
In this case, the template component could be created inside the components folder, **without creating a new folder.
Create a component called PageTemplate.vue, which will contain a dynamic component, that represents the organisms that the content creators have added to our content panel.
The blok object contains an array with the organisms inside of the body.
Each element of the arrays will contain the type of component (block.component): services (the organism).
PageTemplate.vue
Page
The last level will only be a part of our code (view: eg. index).
This is the view that will call the Storyblok API, with a fetch or axios call, and receives the data.
This data is then passed to the corresponding template, in this example page-template. The template will in turn pass the data to the organisms, then to the molecules, and, finally, end up with the atoms.
Passing the data from parent to child.
index.vue
Conclusion
Using Atomic design, we have created an ecosystem that enables content creators to re-use the organisms we defined and fill their related molecules with content.
Every developer uses methodologies that suit their project needs. In this case, I have explained a methodology that will help you to build a Design System. If this makes sense for you too, give it a shot, and let me know how it went!
Resource | URL |
---|---|
Recording of the Talk | https://youtu.be/DThhHwEec8Q |
Demo site | https://dawntraoz.github.io/atomic-design-storyblok/ |
Demo repository | https://github.com/Dawntraoz/atomic-design-storyblok |
Atomic Design Methodology | https://bradfrost.com/blog/post/atomic-web-design/ |
Atomic Design Book | https://atomicdesign.bradfrost.com/ |
Content Types | https://www.storyblok.com/docs/guide/essentials/content-structures#content-type |
Blok (Nested Component) | https://www.storyblok.com/docs/guide/essentials/content-structures#blok-nestable-component |