Create and Render Blog Articles in Storyblok and Astro
Storyblok is the first headless CMS that works for developers & marketers alike.
In this part, we’ll add a blog to our website. More specifically, we’ll include featured articles on the home page and an overview of all articles on a dedicated blog page. Along the way, you’ll learn many exciting things, including how to create and manage folders in Storyblok, how to reference stories in a multi-options field and how to resolve relations using the Storyblok Content Delivery API. Are you ready? Let’s get started!
In a hurry? Check out the source code on GitHub and take a look at the live version on Netlify.
Requirements
This tutorial is part 5 of the Ultimate Tutorial Series for Astro. We recommend that you follow the previous tutorials before starting this one.
Creating a new Content Type Block for the Blog Articles
First of all, we need to consider how we would like to manage our blog articles. As of right now, we have just one content type block: the page
block for all of our pages. This particular block allows for a lot of flexibility in arranging nested blocks exactly how a content creator might need them in a variety of different use cases. However, when it comes to blog articles, we most likely need less flexibility and more coherency instead. Therefore, we need to consider what a blog article would typically consist of and how that would translate to our selection of Storyblok fields. Let’s go for the following fields:
image
: field type Asset {1}title
: field type Text {2}teaser
: field type Textarea {3}content
: field type Richtext {4}
Alright, so let’s create our new content type block - let’s call it article
:
Managing all Articles from a Dedicated Folder
In order to keep everything nice and tidy, Storyblok makes it easy for you to manage all of your content in folders. Let’s create a new folder called Blog to organize all of our blog articles. When creating a new folder, you can even choose to set the default content type, so we can employ article
block we just created {1}:
Now you can click on the fresh new folder and whenever you create a new story, it will be of the type article
by default.
Once you’ve created the first article, you’ll see the schema we set up in action:
At this point, I would suggest creating 3-4 articles with some dummy content so that we actually have some articles to choose from later on.
Creating a Nested Block for Featured Articles
Having taken care of the block schema for our articles, we can now move on and create a new nested block called popular-articles
. This will be used to choose up to three articles that should be displayed in a preview format. For that block, we need to define the following fields:
headline
: field type Text {1}articles
: field type Multi-Options {2}
Let’s create it:
For the articles
field, we need to take some additional steps to configure it properly. First of all, we have to select Stories as the Source of our available options {1}. Since it should not be possible to select just any story, we can now take advantage of the Blog folder we set up earlier. Simply set blog/
as a value for Path to folder of stories {2}. Additionally, we should make sure only stories of the content type article
are included in the options to choose from {3}. Finally, let’s limit the maximum number of articles that can be selected to 3
{4}.
Once you’ve created this block, you can use it anywhere on the Home story (at the root level of the content section in the Storyblok Space) and select up to three of your previously created articles.
Creating a Nested Block for All Articles
This nested block is needed to display previews of all existing articles at once. It is fairly straightforward to set up: all that is needed is a new nested block by the name all-articles
with one text field called headline
. The logic to retrieve all articles will be implemented in the frontend.
Once created, this block should be added on the Home story in our Blog folder, where it will serve to render an overview of all blog articles.
Adapting the Astro Project
Fantastic, we’re done with everything we need to configure on the Storyblok side of things - now let’s dive into the code, shall we?
First, we are going to map the components in our astro.config.mjs
file. Once done we can start creating these files and start our coding.
Rendering Single Articles
Now we can create a new component that renders the single view of our articles:
Most of this code should be somewhat familiar to you at this point. However, there are two interesting things happening here. First, we are attaching two parameters to the image url (/m/1600x0
), resulting in an optimized, resized image being generated by the Storyblok Image Service. Second, we are resolving the rich text field we created for the main content of our articles. This is achieved using the built-in renderRichText
function of @storyblok/astro.
When using TailwindCSS, installing the @tailwindcss/typography plugin and using the prose
class results in beautifully formatted text.
If you open any of your articles in the Visual Editor, everything should be rendered correctly now:
Rendering Popular Articles
Next, let’s create another new component that serves to render the selected popular articles.
As you can see, we are looping through the blok.articles
field using a nested ArticleCard.astro
component. Outsourcing the code for the article cards is quite helpful because we can easily reuse it later for All Articles block.
Since this component exclusively exists in our code base but not in the block library of our space, I would suggest putting it in the components
rather than the storyblok
folder. Let’s create the article card component:
Resolving Relations to Retrieve the Popular Articles
Now there’s just one more thing we need to take care of in order to have our Popular Articles block render correctly. Right now, the articles
field of our block would only include the uuids
of the stories (blog articles) we referenced. By default, the Storyblok Content Delivery API would only return the data of the main story you are requesting (which would be the Home story in this case, as that is where we included the Popular Articles block earlier). However, using a really convenient API parameter called resolve_relations
, we can retrieve the data of the stories we referenced, too.
In order to do that, we have to specify the block and the field containing the uuids
that should be resolved. We can easily make that change in our […slug.astro]
:
To learn more about how that works, you can head over to the @storyblok/js documentation.
You can experiment with the resolve_relations
parameter by opening the Draft JSON in a new tab and attaching the parameter to the URL, e.g. &resolve_relations=popular-articles.articles
. Resolved stories will be shown in a rels
array at the end of the JSON response.
Wonderful, now our popular articles should show up correctly:
Rendering All Articles
Finally, we also have to create a component that renders all articles:
It is very similar to storyblok/PopularArticles.astro
. However, there is a few extra lines of code we have to write. No worries, let’s go through it together!
Up until now, we’ve always requested a single story from the API. Here, using cdn/stories
, we’re requesting multiple stories. To narrow down our results, we’re employing the starts_with
parameter. In this particular case, we’re telling the API to deliver all stories that exist in our Blog folder. Also, we want to make sure that our Blog Home page is not included. Since it is defined as the root of the folder, we can easily exclude it by setting the is_startpage
parameter to 0
.
Having taken care of that, we can just reuse our ArticleCard.astro
component to loop through our articles and pass on the relevant properties.
And just like that, all of our articles should render correctly on the blog overview page:
Wrapping Up
Congratulations, you’ve completed yet another crucial step on your way to becoming a Storyblok and Astro expert! By now, you have successfully integrated a blog into your website and taken a deeper dive into the Storyblok CMS and its Content Delivery API. While there’s still so much to discover, I hope that the concepts we explored together in this part already help you to gain a more thorough understanding of the workings of Storyblok and how to use these to your advantage when developing your own projects in the future.
Continue reading and learn how to manage multilingual content in Storyblok and Astro.
Resource | Link |
---|---|
Astro | https://astro.build/ |
The Storyblok Astro Ultimate Tutorial | https://www.storyblok.com/tp/the-storyblok-astro-ultimate-tutorial/ |
Storyblok SDK for Astro | https://github.com/storyblok/storyblok-astro |
Storyblok SDK Live Demo | https://stackblitz.com/edit/astro-sdk-demo |
Storyblok in the Astro Docs | https://docs.astro.build/en/guides/cms/storyblok/ |
Building Future-Proof High-Performance Websites With Astro Islands And Headless CMS | https://www.smashingmagazine.com/2023/02/building-future-proof-high-performance-websites-astro-islands-headless-cms-storyblok/ |
Storyblok APIs | https://www.storyblok.com/docs/api |