Create Custom Components in Storyblok and Next.js
Storyblok is the first headless CMS that works for developers & marketers alike.
In this short tutorial, we will see how to start making our own components and extend the existing ones with Next.js and Storyblok. We will add a new Hero
component with two Layout
options in Storyblok, along with the code in our frontend. We will also extend our existing Feature
component by including images and better styling.
If you’re in a hurry, have a look at our live demo in Stackblitz! Alternatively, you can explore or fork the code from the Next Ultimate Tutorial GitHub Repository.
Requirements
This is a part of the Ultimate Tutorial Guide for Next.js. You can find the previous part of the series here, which shows how to render Storyblok stories dynamically in Next.js. We recommend you to take a look at that tutorial before starting this one.
You can also take a look at the optional tutorial of the series - Create Dynamic Menus in Storyblok and Next.js.
We will use the code from the previous tutorial as a starting point. You can find the Stackblitz demo for it here.
Changing the Feature Component
To view all the components, click on the Block Library
tab {1} on the left-hand side as seen in the image.
)
Block Library
Now, let’s edit the Feature
’s schema, and add image
as a new field {1}.
)
Add Image Field
This image field should be of type asset. To change the field type and view other options related to the field, click on the field image.
Change the field type to Asset
{1} and select Images
in the Filetypes
{2}.
)
Change Field Type
We will have to change the code in our Next.js app with the updated fields and styles.
Replace the code of Feature.js
to the following:
...
const Feature = ({ blok }) => (
<div className="column feature" {...storyblokEditable(blok)}>
<div className="p-6">
<img className="object-cover object-center w-full mb-8 lg:h-48 md:h-36 rounded-xl" src={blok.image.filename} alt="feature"/>
<h1 className="mx-auto mb-8 text-2xl font-semibold leading-none tracking-tighter text-neutral-600 lg:text-3xl">{blok.name}</h1>
<div className="mt-4">
<a href="#" className="inline-flex items-center mt-4 font-semibold text-blue-600 lg:mb-0 hover:text-neutral-600" title="read more"> Read More » </a>
</div>
</div>
</div>
);
...
Let’s go ahead and add images to the features of a grid on the about
page. To do that, we need to click on the Grid
and then click on one of the features inside it. We will see that we have a field named image
already present there. We can now add an image to a feature. Let’s add images for other features as well. It should look something like this -
)
Features with Images
Creating a component
Now, let’s create a new Hero
component. To do that, we will need to return to the Block Library
{1} and click on +New Block
at the top right corner {2}.
)
Block Library
Once we click on +New Block
, we can enter the details about our new component. Let’s give it a name hero
{1}, and select the block type Nested
{2}, which is there by default. This will be a Nested component because we will be using it inside other components.
A Content Type Block allows you to create templates for Stories, whereas a Nested Block can only be used inside a Story and other blocks. You can find more information here.
You can hit Add Block
{3} after that.
)
Add Block
We can start adding the fields. We need to create four fields, three of which are-
1. headline
of type text.
2. subheadline
of type text.
3. background_image
of type asset and then select image as we did for feature’s image.
The 4th one will be a layout
field, which will allow us to change the layout of the hero
block. It should be of type Single Option {1}.
)
Layout Field
Now, let’s add two options as key-value pairs {1} for the two types of layout, with a default value {2}.
)
Options for Layout
Let’s hit save and add this component to our home
story. Also, we should add content to the component’s fields. Feel free to use any text and image.
As we added a new component, we will also need to add the component to the frontend code of our project. Create a Hero.js
file inside the components
folder, and add the following code to it.
import { storyblokEditable } from "@storyblok/react";
const Hero = ({ blok }) => {
return (
<div {...storyblokEditable(blok)} className={`min-h-[500px]
relative
flex
items-end
justify-center
p-9
my-6
rounded-[5px]
overflow-hidden ${blok.layout === 'constrained' ? 'container mx-auto' : ''}`}>
<div className="relative z-10 text-center">
<h1 className="text-6xl text-white font-bold mb-3">{blok.headline}</h1>
<h2 className="text-4xl text-white font-light">{blok.subheadline}</h2>
</div>
<img
src={blok.background_image.filename}
alt={blok.background_image.alt}
className="absolute top-0 left-0 z-0 w-full h-full object-cover"
/>
</div>
);
};
export default Hero;
Note that we are changing the styles of the Hero
section depending on the selected layout. This is being done conditionally on line 13.
The only thing left to do is to add this component to our list of dynamic components in _app.js
.
...
import Hero from '../components/Hero'
const components = {
feature: Feature,
grid: Grid,
teaser: Teaser,
page: Page,
hero: Hero
};
...
Save and go back to our Home
story in Storyblok. We will see something like this -
)
Hero with constrained layout
We also have an option to change the layout here. We can choose the other one from the dropdown and we will see the changes.
)
Hero with full width
Wrapping Up
In this tutorial, we saw how to extend and create new components from scratch with different types of fields, along with the integration of those components into the frontend of our application. Congratulations!
In the next part of this series, we will see how to create and render blog articles in Storyblok and Next.js. You can find it here.
Resource | Link |
---|---|
Storyblok Next.js Ultimate Tutorial | https://www.storyblok.com/tp/nextjs-headless-cms-ultimate-tutorial |
Stackblitz Demo | https://stackblitz.com/edit/create-custom-components-in-storyblok-and-next-js |
Storyblok Technologies Hub | https://www.storyblok.com/technologies |
Next.js Technology Hub | Storyblok Next.js Technology Hub |
Storyblok React SDK | storyblok/storyblok-react |