Show the Blog Content in Nuxt Using Storyblok API
Storyblok is the first headless CMS that works for developers & marketers alike.
At this point in the guide, you learned to create a basic blog with static data, and, in the last article, you created the blog structure on Storyblok in order to create:
Now it's time to use the Storyblok Content Delivery API to fetch the blog content and show it in our Nuxt blog.
Use Storyblok API
The easiest way to connect to the Storyblok API is to use the storyblok-nuxt module. Install it:
And add it to the
modules section on your
accessToken option, you need to write your Storyblok access token key. Let's load it from a
.env file using the
STORYBLOK_KEY key. Thus, you're making sure your environment variables are loaded in a secure and convenient way.
Now create the token on Storyblok. Go to Settings > API Keys and create a new public key. That's the one you'll use to communicate to Storyblok API.
Finally, create the
.env file in the root of your project with the
Now it's all set to start fetching your blog contents.
If you have followed the previous guides up to this point, you should have a
pages/index.vue where you hard-coded the
articles like this:
Now it's time to get the real data from Storyblok API.
Since you installed
storyblok-nuxt, you have the client available on the Nuxt context under the
app.$storyblok key. Let's change the previous code to call the following for fetching the articles using the Storyblok API client:
The API returns a structure like this:
Notice that the data you want is inside the
content key of each object of the array, so let's modify the template in
Run the project and you should see it with the actual data now:
Do you notice anything wrong? Yes, the author is not shown. If you check the API response from above again, you'll notice that
author it's not the author object, but its
To get the author object, you need to resolve the relationship by using the
That call will now return the following structure:
You'll notice it's still not working, but that's just because you need to apply a couple of tweaks to adapt to the new data structure.
components/ui/ArticleCard.vue and update the
<img> tag to the following:
Now you'll see the project is fully working. Go ahead and create more articles and you'll see them in the UI.
The Article Detail Page
You just finished
pages/index.vue where you listed all the articles from Storyblok. But if you click on an article now, the page won't be found:
If you look at the url you can see it's going to
/undefined because we didn't yet define any way to navigate to the article detail.
Let's agree we're going to use the
/:slug route, where
:slug is the dynamic slug of the article.
If you didn't have a
slug property on
ArticleCard.vue, add it now:
pages/index.vue, use the
article.slug property from the article's data to pass that link down:
Notice I'm getting the slug from
article.slug directly. This is because it's a property common to all stories in Storyblok, while what's inside
article.content are the ones defined by us.
The second step is to create the route. According to the Nuxt routing conventions, you need to create a
On the page, the only information you have is the article slug. You don't have the id, the uuid or the full_slug, so you can't retrieve a story like it's mentioned in the docs.
We want to do that for SEO purposes and having friendly urls. Additionally, we'd like to organize the contents freely inside the Articles folder in Storyblok, not worrying about the full_slug.
So how do you do it? You basically need to use the
by_slugs parameter to the same call you are performing to retrieve all articles to get this first result:
by_slugs finds an exact match, but we can prepend a wildcard
*/ so that it includes any path before the slug.
Basically, that call is saying "Find the articles under
articles/ that end with the slug
In this case, we're also returning an
author variable for easy access from the template.
What if the article is not found? Then it will crash for sure. To prevent that from happening, use the
error function from the Nuxt context for error handling:
Add the following template:
At this point, if you navigate to the article detail it should look like this:
So far it's working, but notice a couple of things:
- Markdown is not parsed
- It has no styling
We'll use @nuxtjs/markdownit to easily parse markdown contents.
First, install it:
Then add it to the
modules on your
nuxt.config.js with the following config:
Now you have
$md.render available to use in our components. All you need to do is to use it with the
v-html directive in the
And... here we go!
Extra: Syntax Highlighting for Code Blocks
For syntax highlighting I like to use markdown-it-prism. It's simple and does the job perfectly.
Let's install it by running:
nuxt.config.js and add it to the
use property of the
markdownit options, like this:
Finally, include the stylesheet of the theme of your preference. I like tomorrow dark, and prefer to load it from a CDN, so just add this to the
link property on your
If you don't have any code block in your article on Storyblok, add it (remember to specify the language). Then it should look like this:
When you use
v-html and have no control over what's inside, you need a way to style the inner content.
In this case, you're inserting the HTML rendered from the markdown. There is something made especially for these content-based HTML cases:
The awesome TailwindCSS Typography plugin! You just need to install it:
Then add the plugin to the
tailwind.config.js plugins key:
Finally, add the class
prose to the div containing the parsed markdown in
This is how it'll look:
Doesn't it look beautiful? Trust me, the TailwindCSS Typography plugin is very well thought out for optimized reading. If you want to customize anything, check the docs.
Congrats for reading up to this point! This guide wasn't short and you implemented several features, specifically:
- Installed and configured the Storyblok API client using environment variables
- Fetched all of the articles for the
- Created the
/articles/:slugpage and retrieved the data from Storyblok
- Parsed markdowns, including code syntax highlight, using MarkdownIt and Prism
- Styled raw HTML using the TailwindCSS Typography plugin
With the features you've implemented so far, you know the basics to build any blog right now.
But... what about categorization? And SEO? And a search box to find articles?
Everything will come soon!
Got into trouble? You can go to the Github repo and see the code of this lesson. Feel free to play with it!
In the next article, you will read about how to set up Tags and Search Functionality in Nuxt Using Storyblok API.