Design Converter
Education
Developer Advocate
Last updated on Nov 7, 2023
Last updated on Nov 6, 2023
Storyblok and React together form a powerful combination for developers looking to create dynamic, content-rich applications. Storyblok is a headless CMS that allows you to manage and organize your content, while React is a popular JavaScript library for building user interfaces. Using them together, you can manage your content in Storyblok and then display it in your React application.
Before you can start using Storyblok with React, install the "@storyblok/react" npm package. This package provides the necessary tools to integrate Storyblok into your React application. You can install it by running the following command in your terminal:
1npm install @storyblok/react
or if you prefer using yarn:
1yarn add @storyblok/react
The Storyblok API client is a crucial part of integrating Storyblok with React. It allows your React application to communicate with Storyblok's API and fetch the content you've created in your app from Storyblok space.
You can use the Storyblok API client in your React components to fetch data. Here's an example of how you might use it:
1import StoryblokClient from 'storyblok-js-client' 2 3const Storyblok = new StoryblokClient({ 4 accessToken: 'YOUR_ACCESS_TOKEN' 5}) 6 7export default function Home() { 8 const [data, setData] = React.useState(null) 9 10 React.useEffect(() => { 11 Storyblok.get('cdn/stories/home') 12 .then((response) => { 13 setData(response.data) 14 }) 15 .catch((error) => { 16 console.log(error) 17 }) 18 }, []) 19 20 if (!data) { 21 return <div>Loading...</div> 22 } 23 24 return ( 25 <div> 26 <h1>{data.story.name}</h1> 27 <p>{data.story.content.intro}</p> 28 </div> 29 ) 30} 31
In this example, we use the Storyblok API client to fetch the home story from our Storyblok space. We then display the name and intro of the story in our React component.
A Storyblok space is where you create, manage, and organize your content. Each space has its content, components, and assets. Here's how you can create a new space:
Once you've created a space, you can start adding content to it. Each piece of content in Storyblok is called a "story".
In Storyblok, a component is a reusable piece of content. You can create different components, such as text blocks, images, and sliders, and use them in your stories.
In your React application, you can create a corresponding React component for each Storyblok component. You can then use the components object in your React components to determine which React component to render based on the type of the Storyblok component.
Here's an example of how you might use the components object in a React component:
1import React from 'react' 2import StoryblokClient from 'storyblok-js-client' 3 4const Storyblok = new StoryblokClient({ 5 accessToken: 'YOUR_ACCESS_TOKEN' 6}) 7 8const components = { 9 'text': (props) => <p>{props.content.text}</p>, 10 'image': (props) => <img src={props.content.src} alt={props.content.alt} />, 11 // Add more components as needed 12} 13 14export default function Home() { 15 const [data, setData] = React.useState(null) 16 17 React.useEffect(() => { 18 Storyblok.get('cdn/stories/home') 19 .then((response) => { 20 setData(response.data) 21 }) 22 .catch((error) => { 23 console.log(error) 24 }) 25 }, []) 26 27 if (!data) { 28 return <div>Loading...</div> 29 } 30 31 return ( 32 <div> 33 {data.story.content.body.map((blok) => { 34 const Component = components[blok.component] 35 return Component ? <Component content={blok} /> : null 36 })} 37 </div> 38 ) 39} 40
In this example, we're mapping over the body of the story, which is an array of Storyblok components. For each Storyblok component, we're using the components object to determine which React component to render.
One of the key features of Storyblok is its visual editor. The visual editor lets you see a live preview of your content as you edit it in Storyblok. This can be incredibly useful for seeing how your content will look in your React application.
To integrate the Storyblok visual editor with your React application, you can use the storyblok-react package. This package provides a StoryblokBridge component that you can use to connect your React application to the Storyblok visual editor.
Here's an example of how you might use the StoryblokBridge component in your React application:
1import React from 'react' 2import { StoryblokBridge, useStoryblok } from '@storyblok/react' 3 4export default function Home({ story }) { 5 const storyblokStory = useStoryblok(story) 6 7 return ( 8 <div> 9 <h1>{storyblokStory.name}</h1> 10 <p>{storyblokStory.content.intro}</p> 11 <StoryblokBridge /> 12 </div> 13 ) 14} 15
In this example, we use the useStoryblok hook to connect our React component to the Storyblok visual editor. We're then using the StoryblokBridge component to add all your components and enable the live preview functionality.
The @storyblok/react package also provides a StoryblokEditable component and a storyblokInit function that you can use further to enhance the integration between your React application and Storyblok.
The StoryblokEditable component allows you to make your React components editable in the Storyblok visual editor. You can wrap your React components in a StoryblokEditable component to make them editable.
The storyblokInit function allows you to initialize the Storyblok editor. You can call this function in your React component to initialize the editor.
Here's an example of how you might use the StoryblokEditable component and the storyblokInit function in your React application:
1import React from 'react' 2import { StoryblokBridge, useStoryblok, StoryblokEditable } from '@storyblok/react' 3 4export default function Home({ story }) { 5 const storyblokStory = useStoryblok(story) 6 7 React.useEffect(() => { 8 StoryblokBridge.storyblokInit() 9 }, []) 10 11 return ( 12 <StoryblokEditable blok={storyblokStory}> 13 <div> 14 <h1>{storyblokStory.name}</h1> 15 <p>{storyblokStory.content.intro}</p> 16 </div> 17 </StoryblokEditable> 18 ) 19} 20
In this example, we use the useEffect hook to call the storyblokInit function when our React component mounts. We're wrapping our content in a StoryblokEditable component to make it editable in the Storyblok visual editor.
Once you've set up your Storyblok space and created all your components and content, you can use the Storyblok API to retrieve your content and display it in your React application. The Storyblok API provides several endpoints that you can use to fetch your stories, components, and assets.
To query the Storyblok API, you can use the get method provided by the Storyblok client. You pass the path of the endpoint you want to query to the get method, and it returns a promise that resolves with the data from the API.
Here's an example of how you might query the Storyblok API in a React component:
1import React from 'react' 2import StoryblokClient from 'storyblok-js-client' 3 4const Storyblok = new StoryblokClient({ 5 accessToken: 'YOUR_ACCESS_TOKEN' 6}) 7 8export default function Home() { 9 const [data, setData] = React.useState(null) 10 11 React.useEffect(() => { 12 Storyblok.get('cdn/stories/home') 13 .then((response) => { 14 setData(response.data) 15 }) 16 .catch((error) => { 17 console.log(error) 18 }) 19 }, []) 20 21 if (!data) { 22 return <div>Loading...</div> 23 } 24 25 return ( 26 <div> 27 <h1>{data.story.name}</h1> 28 <p>{data.story.content.intro}</p> 29 </div> 30 ) 31} 32
In this example, we use the useEffect hook to query the Storyblok API when our React component mounts. We're querying the cdn/stories/home endpoint, which fetches the home story from our Storyblok space. We then set the data from the API as the state of our React component and display it in our component.
When working with Storyblok and React, you might encounter situations where you need to conditionally render different components based on the type of the Storyblok component. This can be achieved by creating a mapping between Storyblok components and React components, and then using this mapping to render the appropriate React component conditionally.
Here's an example of how you might handle conditional component returns in a React component:
1import React from 'react' 2import StoryblokClient from 'storyblok-js-client' 3import TextBlock from './components/TextBlock' 4import ImageBlock from './components/ImageBlock' 5 6const Storyblok = new StoryblokClient({ 7 accessToken: 'YOUR_ACCESS_TOKEN' 8}) 9 10const components = { 11 'textBlock': (props) => <TextBlock {...props} />, 12 'imageBlock': (props) => <ImageBlock {...props} />, 13 // Add more components as needed 14} 15 16export default function Home() { 17 const [data, setData] = React.useState(null) 18 19 React.useEffect(() => { 20 Storyblok.get('cdn/stories/home') 21 .then((response) => { 22 setData(response.data) 23 }) 24 .catch((error) => { 25 console.log(error) 26 }) 27 }, []) 28 29 if (!data) { 30 return <div>Loading...</div> 31 } 32 33 return ( 34 <div> 35 {data.story.content.body.map((blok) => { 36 const Component = components[blok.component] 37 return Component ? <Component {...blok} /> : null 38 })} 39 </div> 40 ) 41} 42
In this example, we're mapping over the body of the story, which is an array of Storyblok components. For each Storyblok component, we're using the components object to determine which React component to render. If a matching React component is found, it is rendered with the Storyblok component's props. If no matching React component is found, null is returned.
Storyblok's API is not just for fetching content. It also allows you to create, update, and delete content in your Storyblok space. This can be incredibly useful for managing your content directly from your React application.
To create, update, or delete content, you can use the post, put, and delete methods provided by the Storyblok client. These methods work similarly to the get method, but they also require you to pass an object with the data you want to send to the API.
Here's an example of how you might use the Storyblok API to manage content in a React component:
1import React from 'react' 2import StoryblokClient from 'storyblok-js-client' 3 4const Storyblok = new StoryblokClient({ 5 accessToken: 'YOUR_ACCESS_TOKEN' 6}) 7 8export default function Home() { 9 const [data, setData] = React.useState(null) 10 11 const createStory = () => { 12 const newStory = { 13 name: 'New Story', 14 slug: 'new-story', 15 content: { 16 intro: 'This is a new story.' 17 } 18 } 19 20 Storyblok.post('cdn/stories', { story: newStory }) 21 .then((response) => { 22 setData(response.data) 23 }) 24 .catch((error) => { 25 console.log(error) 26 }) 27 } 28 29 return ( 30 <div> 31 <button onClick={createStory}>Create Story</button> 32 {data && ( 33 <div> 34 <h1>{data.story.name}</h1> 35 <p>{data.story.content.intro}</p> 36 </div> 37 )} 38 </div> 39 ) 40} 41
In this example, we use the post method to create a new story in our Storyblok space. We're passing an object with the data for the new story to the post method. Once the new story is created, we set the data from the API as the state of our React component and display it in our component.
Storyblok offers a range of advanced features that can help you optimize your React application. One of these features is CDN Stories, which allows you to fetch multiple stories from a plugin on your application to Storyblok space in a single API request. This can be incredibly useful for reducing the number of API requests your application needs to make.
Another advanced feature is revalidation, which allows you to specify how often your data should be revalidated. This can be useful for ensuring your data is always up to date, even if it changes frequently.
Here's an example of how you might use CDN Stories and revalidation in a React component:
1import React from 'react' 2import StoryblokClient from 'storyblok-js-client' 3 4const Storyblok = new StoryblokClient({ 5 accessToken: 'YOUR_ACCESS_TOKEN' 6}) 7 8export default function Home() { 9 const [data, setData] = React.useState(null) 10 11 React.useEffect(() => { 12 Storyblok.get('cdn/stories', { version: 'published' }) 13 .then((response) => { 14 setData(response.data.stories) 15 }) 16 .catch((error) => { 17 console.log(error) 18 }) 19 }, []) 20 21 if (!data) { 22 return <div>Loading...</div> 23 } 24 25 return ( 26 <div> 27 {data.map((story) => ( 28 <div key={story.id}> 29 <h1>{story.name}</h1> 30 <p>{story.content.intro}</p> 31 </div> 32 ))} 33 </div> 34 ) 35} 36 37export async function getStaticProps() { 38 const res = await Storyblok.get('cdn/stories', { version: 'published' }) 39 const data = res.data.stories 40 41 return { 42 props: { 43 data, 44 }, 45 revalidate: 3600, // Revalidate every hour 46 } 47} 48
In this example, we're using the get method to fetch all the published stories from our Storyblok space. We're then mapping over the stories and displaying each one in our React component. We also use the getStaticProps function to fetch the stories at build time and revalidate the data every hour.
Storyblok and React offer a powerful solution for building dynamic, content-rich applications. By leveraging the power of Storyblok's headless CMS and React's component-based architecture, you can create applications that are easy to manage, highly performant, and incredibly user-friendly.
Whether you're a seasoned developer or just getting started, Storyblok and React offer many possibilities for your next project.
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.