@storyblok/react
@storyblok/react is Storyblok’s official development for React applications.
Requirements
Section titled “Requirements”- React version 17 or later
- Node.js LTS (version 22.x recommended)
- Modern web browser (e.g., Chrome, Firefox, Safari, Edge – latest versions)
Installation
Section titled “Installation”Add the package to a project by running this command in the terminal:
npm install @storyblok/react@latestConfiguration
Section titled “Configuration”Import and initialize the SDK using the access token of a Storyblok space.
import { apiPlugin, storyblokInit } from "@storyblok/react";import Page from "./Page.js";import Feature from "./Feature.js";
storyblokInit({ accessToken: "YOUR_ACCESS_TOKEN", use: [apiPlugin], apiOptions: { region: "eu", }, components: { page: Page, feature: Feature, },});Components
Section titled “Components”Create a React component for each block defined in Storyblok and registered in the configuration. Each component will receive a blok prop, containing the content of the block.
const Feature = ({ blok }) => ( <div> <h2>{blok.headline.text}</h2> </div>);
export default Feature;Use <StoryblokComponent> to automatically render nested components (provided they are registered globally).
import { StoryblokComponent } from "@storyblok/react";
export default function Page({ blok }) { return <section>{blok.body ? blok.body.map((blok) => <StoryblokComponent blok={blok} key={blok._uid} />) : null}</section>;}Fetching and rendering
Section titled “Fetching and rendering”Use the client to fetch a story and render the content using StoryblokComponent.
import { StoryblokComponent, useStoryblok } from "@storyblok/react";
export default function App() { const story = useStoryblok("home", { version: "draft", }); if (!story?.content) { return <div>Loading...</div>; } return <StoryblokComponent blok={story.content} />;}React Server Components
Section titled “React Server Components”This SDK provides a special module for React Server Components (RSC). Always import from @storyblok/react/rsc while using Server Components.
storyblokInit
Section titled “storyblokInit”Import and initialize the SDK to access and configure all features.
import { storyblokInit } from "@storyblok/react";
storyblokInit(OPTIONS);storyblokInit() creates an instance of the Storyblok API client and loads the Storyblok Bridge.
All options listed in the @storyblok/js package reference are available. The following additional options are available:
| Key | Description | Type |
|---|---|---|
components | An object that maps React components to Storyblok blocks. Each component receives a blok prop containing the content of the block. | object |
enableFallbackComponent | Enable or disable a fallback component to be rendered if no React component has been defined for a Storyblok block. Disabled by default. | boolean |
customFallbackComponent | Register a custom fallback component. Requires enableFallbackComponent to be enabled. | React component |
apiPlugin
Section titled “apiPlugin”apiPlugin configures the implementation of the Storyblok API. It is imported from @storyblok/js.
import { storyblokInit, apiPlugin } from "@storyblok/react";
storyblokInit({ use: [apiPlugin] });See the @storyblok/js reference for further details.
useStoryblok
Section titled “useStoryblok”Enable both data fetching and bridge capabilities using this function.
import { useStoryblok } from "@storyblok/react";
export default function App() { const story = useStoryblok(URL, API_OPTIONS, BRIDGE_OPTIONS);}For the API_OPTIONS, see the storyblok-js-client reference. For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.
useStoryblokApi
Section titled “useStoryblokApi”useStoryblokApi() returns the client instantiated in the application.
import { useStoryblokApi } from "@storyblok/react";import { useEffect, useState } from "react";
export default function App() { const storyblokApi = useStoryblokApi(); const [data, setData] = useState(null);
useEffect(() => { async function fetchData() { const response = await storyblokApi.get(URL, API_OPTIONS); setData(response.data); } fetchData(); }, []);}For the API_OPTIONS, see the storyblok-js-client reference.
getStoryblokApi
Section titled “getStoryblokApi”getStoryblokApi() is an alias of useStoryblokApi().
useStoryblokBridge
Section titled “useStoryblokBridge”useStoryblokBridge() activates the Storyblok Bridge.
import { useStoryblokApi, useStoryblokBridge } from "@storyblok/react";import { useEffect, useState } from "react";
export default function App() { const storyblokApi = useStoryblokApi(); const [data, setData] = useState(null);
useEffect(() => { async function fetchData() { const response = await storyblokApi.get(URL, API_OPTIONS); setData(response.data); } fetchData(); }, []);
useStoryblokBridge(STORY_ID, CALLBACK, BRIDGE_OPTIONS);}For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.
It is possible to access the Storyblok Bridge via window instead of using useStoryblokBridge as shown below:
const storyblokBridge = new window.StoryblokBridge(options);
storyblokBridge.on(["input", "published", "change"], (event) => { // ...});registerStoryblokBridge
Section titled “registerStoryblokBridge”registerStoryblokBridge() is an alias of useStoryblokBridge().
loadStoryblokBridge
Section titled “loadStoryblokBridge”Activates the Storyblok Bridge on the window.
loadStoryblokBridge();useStoryblokState
Section titled “useStoryblokState”useStoryblokState() accepts a story from the Storyblok API and makes it reactive for live editing.
import { useStoryblokState } from "@storyblok/react";
export default function Home({ story: STORY_OBJECT }) { const story = useStoryblokState(STORY_OBJECT);
if (!story.content) { return <div>Loading...</div>; }}StoryblokStory
Section titled “StoryblokStory”StoryblokStory maintains the state of a story and uses StoryblokComponent to render the route components dynamically, using the list of components loaded via storyblokInit. Use StoryblokComponent inside components to render nested components dynamically.
StoryblokStory accepts a story from the Storyblok API and bridge options.
<StoryblokStory story={STORY_OBJECT} bridgeOptions={BRIDGE_OPTIONS} />For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.
StoryblokComponent
Section titled “StoryblokComponent”StoryblokComponent is a React component that dynamically renders blocks from Storyblok.
StoryblokComponent accepts a blok prop, which should be a block from the Storyblok API. Any other props passed to StoryblokComponent will be passed directly to the block component.
<StoryblokComponent blok={blok} />Use it to iterate over blocks fields as follows:
{ blok.nested_bloks?.map((currentBlok, index) => <StoryblokComponent blok={currentBlok} key={currentBlok._uid || index} />);}StoryblokServerComponent
Section titled “StoryblokServerComponent”Use StoryblokServerComponent rather than StoryblokComponent when using React Server Components.
storyblokEditable
Section titled “storyblokEditable”storyblokEditable() accepts a block from the Storyblok API and returns an object containing the HTML attributes to make elements editable in the Storyblok Visual Editor. See the @storyblok/js reference for further details.
const Feature = ({ blok }) => { return ( <section {...storyblokEditable(blok)} key={blok._uid}> {blok.title} </section> );};setComponents
Section titled “setComponents”setComponents() updates the component map of the current client instance.
setComponents(COMPONENTS_OBJECT);StoryblokRichText
Section titled “StoryblokRichText”Used to render a rich text field from a story.
<StoryblokRichText doc={blok.richtext_field} />See the @storyblok/richtext reference for further details.
Example: Override default resolvers
Section titled “Example: Override default resolvers”Override the default resolvers by passing a resolvers prop to the StoryblokRichText component (for example, to use the Next.js link component or add a custom code block component).
import { StoryblokRichText, useStoryblok, MarkTypes, type StoryblokRichTextNode } from "@storyblok/react";import Link from "next/link";import CodeBlock from "./components/CodeBlock";
function App() { const story = useStoryblok("home", { version: "draft" });
if (!story?.content) { return <div>Loading...</div>; }
const resolvers = { [MarkTypes.LINK]: (node: StoryblokRichTextNode<ReactElement>) => { return node.attrs?.linktype === "story" ? ( <Link href={node.attrs?.href} target={node.attrs?.target}> {node.text} </Link> ) : ( <a href={node.attrs?.href} target={node.attrs?.target}> {node.text} </a> ); }, [BlockTypes.CODE_BLOCK]: (node) => <CodeBlock class={node?.attrs?.class}>{node.children}</CodeBlock>, };
return ( <div> <StoryblokRichText doc={story.content.richText} resolvers={resolvers} /> </div> );}StoryblokServerRichtText
Section titled “StoryblokServerRichtText”Use StoryblokServerRichText rather than StoryblokRichText when using React Server Components.
useStoryblokRichText
Section titled “useStoryblokRichText”Use this function to programmatically render a rich text field.
import { useStoryblokRichText, convertAttributesInElement } from "@storyblok/react";
function App() { const { render } = useStoryblokRichText();
const html = render(doc); const formattedHtml = convertAttributesInElement(html as React.ReactElement);
return <div ref={ref}>{formattedHtml}</div>;}See the @storyblok/richtext reference for further details.
Further resources
Section titled “Further resources”Was this page helpful?
This site uses reCAPTCHA and Google's Privacy Policy. Terms of Service apply.
Get in touch with the Storyblok community