Blog

Storyblok & Next.js quickstart guide

Learn how to integrate Storyblok with Next.js and fetch content with React server components.

Published July 18, 2024 (Updated July 18, 2024)

In this short 5-minute tutorial you will learn how to fetch data from Storyblok in Next.js by creating a concert event website. Storyblok and Next.js are both great tools to build a content-driven website with a clean content editing interface.

You will build a small Next.js website that fetches concerts from Storyblok and displays their information. By the end of this tutorial, you will have the necessary skills to model different types of content in Storyblok and fetch it in Next.js.

Copy the tutorial code from GitHub https://github.com/AustinShelby/storyblok-nextjs-quickstart-guide.

Prerequisites

Before starting this tutorial, you will need:

Model content in Storyblok

In your newly created Storyblok space navigate to the Block Library section, click on New Block, and create a Content type block with the technical name concert.

Storyblok create Content type block

You can think of blocks in Storyblok like tables in SQL databases. They can have different fields with different types such as text, numbers, or images. Stories in Storyblok are like rows in SQL databases. Based on this concert block we will create multiple stories that we can then fetch in Next.js.

Once we have created our concert block let's add the necessary fields to it.

Add the following fields with the types.

  • band. Text

  • venue. Text

  • date. Date/Time

  • description. Textarea

Storyblok add fields to block

Now that we have created our block let's move on to the Content section and create a few stories with our newly created block.

Create Storyblok stories

Click on Create new and then Story.

Give your story a descriptive name and change the Content type to Concert.

Storyblok create a new story

Notice how the Slug gets automatically populated. We will use this value to fetch a specific story in Next.js.

Click on Create and move to add content.

Fill in the Band, Venue, Date, and Description fields for your concert.

Storyblok add data to a story

Once you have added all the content hit on Publish and move over to Next.js.

Integrate Next.js with Storyblok

In a fresh Next.js project install the required package @storyblok/react using either npm or yarn.

npm install @storyblok/react
yarn add @storyblok/react

After installing the package, initialize Storyblok in the root layout of your application found on the file src/app/layout.tsx.

src/app/layout.tsx
1import { storyblokInit, apiPlugin } from "@storyblok/react";
2import { PropsWithChildren } from "react";
3
4storyblokInit({
5 accessToken: process.env.STORYBLOK_ACCESS_TOKEN,
6 use: [apiPlugin],
7});
8
9const RootLayout = ({ children }: PropsWithChildren) => {
10 return (
11 <html lang="en">
12 <body>{children}</body>
13 </html>
14 );
15};
16
17export default RootLayout;
Next.js root layout initialize storyblok

On line 1, import the required functions storyblokInit and apiPlugin from @storyblok/react.

On line 4, call the storyblokInit function, set the accessToken to the environment variable STORYBLOK_ACCESS_TOKEN, and use the apiPlugin.

In production environments like Vercel or DigitalOcean, set the STORYBLOK_ACCESS_TOKEN environment variable using their interface but in your local Next.js development environment, use a special file .env.local.

Next.js automatically creates environment variables from the .env.local file. Make sure that this file isn't committed to the repository by adding it to the .gitignore file.

To find your Storyblok access token go to Settings and click Access Tokens.

Storyblok access token

Copy the access token and paste it into the .env.local file for the variable STORYBLOK_ACCESS_TOKEN.

.env.local
STORYBLOK_ACCESS_TOKEN=Vr7lL1xYoSBN6Ws5XLjFPwtt

Fetch multiple stories from Storyblok

Navigate to the home page file found on src/app/page.tsx.

src/app/page.tsx
1import { getStoryblokApi } from "@storyblok/react";
2import Link from "next/link";
3
4const HomePage = async () => {
5 const client = getStoryblokApi();
6 const response = await client.getStories({ content_type: "concert" });
7
8 return (
9 <ul>
10 {response.data.stories.map((story) => (
11 <li key={story.id}>
12 <Link href={story.slug}>{story.name}</Link>
13 </li>
14 ))}
15 </ul>
16 );
17};
18
19export default HomePage;
Storyblok fetch multiple stories in Next.js

On line 1, import getStoryblokApi from @storyblok/react. We will use this function to get the Storyblok client that we initialized in our root layout file.

On line 5, get the Storyblok client.

On line 6, call the getStories method and in the parameters set the content_type to concert. This way we will only fetch the stories that have a content type of a concert that we created earlier.

On line 10, map over the stories and render a link for each story that points to its slug.

Fetch a Storyblok story based on its slug

Under src/app create a folder [slug] and a file page.tsx inside of it. This will be the dynamic page for individual concerts.

Populate the file with the following code to fetch a story based on its slug.

src/app/[slug]/page.tsx
1import { getStoryblokApi } from "@storyblok/react";
2
3const ConcertPage = async (props: any) => {
4 const client = getStoryblokApi();
5 const response = await client.getStory(props.params.slug, {});
6
7 return (
8 <div>
9 <h1>{response.data.story.content.band}</h1>
10 <p>{response.data.story.content.date}</p>
11 <p>{response.data.story.content.venue}</p>
12 <p>{response.data.story.content.description}</p>
13 </div>
14 );
15};
16
17export default ConcertPage;
Storyblok fetch story based on its slug in Next.js

On line 1, just like on the home page import getStoryblokApi from @storyblok/react.

On line 4, get the Storyblok client.

On line 5, fetch a story based on the page's slug that we get from its props. Note that the getStory method takes two parameters. The story's slug and optional parameters.

On lines 9 to 12, render the concert's band, date, venue, and description.

Extra tips

To render dates and multiline text more beautifully we can use a few tricks.

Turn the date into a JavaScript Date object and call the toLocaleString method to format it nicely.

For the multiline text, set the element's whiteSpace style to pre-line.

src/app/[slug]/page.tsx
1import { getStoryblokApi } from "@storyblok/react";
2
3const ConcertPage = async (props: any) => {
4 const client = getStoryblokApi();
5 const response = await client.getStory(props.params.slug, {});
6
7 return (
8 <div>
9 <h1>{response.data.story.content.band}</h1>
10 <p>
11 {new Date(response.data.story.content.date).toLocaleString("en-US", {
12 dateStyle: "long",
13 timeStyle: "short",
14 })}
15 </p>
16 <p>{response.data.story.content.venue}</p>
17 <p style={{ whiteSpace: "pre-line" }}>
18 {response.data.story.content.description}
19 </p>
20 </div>
21 );
22};
23
24export default ConcertPage;
Format Storyblok dates and multiline text in Next.js

If you are interested in learning Storyblok and Next.js more in-depth, I recommend watching my full-length tutorial that takes you from zero to hero.

Storyblok & Next.js Complete Travel Website Tutorial | Visual Editor, TailwindCSS, Vercel

In this video tutorial you will learn how to:

  • Dynamically render Storyblok blocks.

  • Enable live visual editing with Storyblok.

  • Optimize images for fast first contentful paint.

  • Render rich-text content.

  • Deploy to Vercel.

Conclusion

To fetch data from Storyblok in Next.js you need to:

  • Install @storyblok/react package.

  • Initialize the Storyblok client in your app's root layout file with your access token.

  • In your pages, get the Storyblok API client and call the getStory or getStories methods.


Austin Shelby

Austin Shelby

I am a freelance software engineer, instructor, and public speaker with over half a decade of hands-on experience in the entire software development process. I am passionate about building high-performing web applications and sharing what I have learned along the way.