@storyblok/react (Version 7.x)
@storyblok/react is Storyblok’s official SDK for React applications. A release candidate of version 8.x is available in the @storyblok/react (Version 8.x RC) reference.
Requirements
Section titled “Requirements”- React version 17 or later
- Node.js LTS (version 22.x recommended)
- Modern web browser (for example, Chrome, Firefox, Safari, or Edge)
Installation
Section titled “Installation”Add the package to a project by running this command in the terminal:
npm install @storyblok/react@7| Export | When to use | How to use |
|---|---|---|
@storyblok/react |
Client-rendered single-page apps. | Use useStoryblok and StoryblokComponent. |
@storyblok/react/ssr |
Static rendering and static export (including Next.js output: 'export'). Live editing isn’t supported. |
Use StoryblokServerStory for rendering components. The Storyblok Bridge isn’t loaded. |
@storyblok/react/rsc |
Next.js App Router and other React Server Components setups. | Use StoryblokStory in Server Components so the Storyblok Bridge and live editing work in the Visual Editor. Use StoryblokServerComponent for nested blocks and StoryblokComponent in Client Components. |
Configuration
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 receives a blok prop that contains 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 the configuration registers the nested components).
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} />;}@storyblok/react exports the following functions, hooks, and 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 that renders when a Storyblok block has no React component. Disabled by default. | boolean |
customFallbackComponent |
Register a custom fallback component. Requires enableFallbackComponent. |
React component |
apiPlugin
Section titled “apiPlugin”apiPlugin configures the implementation of the Storyblok API. The plugin comes from @storyblok/js.
import { storyblokInit, apiPlugin } from "@storyblok/react";
storyblokInit({ use: [apiPlugin] });Learn more in the @storyblok/js reference.
useStoryblok
Section titled “useStoryblok”Enable both data fetching and Storyblok Bridge capabilities with useStoryblok.
import { useStoryblok } from "@storyblok/react";
export default function App() { const story = useStoryblok(URL, API_OPTIONS, BRIDGE_OPTIONS);}For the API_OPTIONS, refer to the storyblok-js-client reference. For the BRIDGE_OPTIONS, refer to 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, refer to 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, refer to the @storyblok/preview-bridge reference.
To access the Storyblok Bridge via window instead of useStoryblokBridge, use the following code:
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 the story 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 Storyblok Bridge options.
<StoryblokStory story={STORY_OBJECT} bridgeOptions={BRIDGE_OPTIONS} />For the BRIDGE_OPTIONS, refer to the @storyblok/preview-bridge reference.
StoryblokServerStory
Section titled “StoryblokServerStory”StoryblokServerStory renders a story with StoryblokServerComponent without loading the Storyblok Bridge, so live editing isn’t available. Use StoryblokServerStory with @storyblok/react/ssr for server-side rendering and static export. @storyblok/react/rsc also exports it.
<StoryblokServerStory story={STORY_OBJECT} />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. StoryblokComponent passes any other props directly to the block component.
<StoryblokComponent blok={blok} />Use StoryblokComponent to iterate over block 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. Learn more in the @storyblok/js reference.
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 Storyblok story.
<StoryblokRichText document={blok.richtext_field} />The component accepts the following optional props:
componentssets custom React components for supported rich text nodes and marks.optimizeImagesets image optimization options for image nodes.datashares custom data with all custom rich text components. Each component receives the data ascontext.data.
Find the supported rich text nodes and marks, and the customization options, in the @storyblok/richtext reference.
Custom components
Section titled “Custom components”To register custom components, use the components prop. The key must match a supported rich text node or mark name.
import type { StoryblokReactRichTextComponentMap } from "@storyblok/react";
const components: StoryblokReactRichTextComponentMap = { heading: CustomHeading, link: CustomLink, table: CustomTable, bold: ({ children }) => <b className="font-bold text-black">{children}</b>,};Then pass the components to StoryblokRichText:
<StoryblokRichText document={blok.richtext_field} components={components} />Example: custom link component (mark)
Section titled “Example: custom link component (mark)”Marks receive their rendered child content through the children prop.
import type { StoryblokReactRichTextProps } from "@storyblok/react";import Link from "next/link";
export function CustomLink({ children, attrs }: StoryblokReactRichTextProps<"link">) { return ( <Link href={attrs?.href ?? ""} target={attrs?.target ?? "_self"}> {children} </Link> );}Example: custom heading component (node)
Section titled “Example: custom heading component (node)”Nodes can use the children prop to render child content.
import type { StoryblokReactRichTextProps } from "@storyblok/react";
export function CustomHeading({ children, attrs }: StoryblokReactRichTextProps<"heading">) { const Tag = `h${attrs?.level ?? 1}` as keyof JSX.IntrinsicElements;
return <Tag className="custom-heading">{children}</Tag>;}Example: custom table component (advanced node)
Section titled “Example: custom table component (advanced node)”For advanced use cases, nodes can access content and context to recursively render child nodes using StoryblokRichText.
To separate table header rows from body rows in custom table components, use the splitTableRows utility.
import { StoryblokRichText, splitTableRows, type StoryblokReactRichTextProps } from "@storyblok/react";
export function CustomTable({ content, context }: StoryblokReactRichTextProps<"table">) { const { headerRows, bodyRows } = splitTableRows(content);
return ( <table className="custom-table"> {headerRows.length > 0 && ( <thead> <StoryblokRichText document={headerRows} {...context} /> </thead> )}
<tbody> <StoryblokRichText document={bodyRows} {...context} /> </tbody> </table> );}StoryblokServerRichText
Section titled “StoryblokServerRichText”When working with React Server Components, use StoryblokServerRichText instead of StoryblokRichText.
StoryblokServerRichText provides the same API as StoryblokRichText, including support for the components and optimizeImage props.
useStoryblokRichText
Section titled “useStoryblokRichText”Use useStoryblokRichText to programmatically render rich text content.
import { useStoryblokRichText, type StoryblokReactRichTextComponentMap } from "@storyblok/react";import CustomLink from "./CustomLink";
const components: StoryblokReactRichTextComponentMap = { link: CustomLink,};
function App() { const render = useStoryblokRichText({ components });
const richText = render(blok.articleContent);
return richText;}useStoryblokRichText accepts the same configuration options as StoryblokRichText, including components and optimizeImage.
useStoryblokServerRichText
Section titled “useStoryblokServerRichText”When working with React Server Components, use useStoryblokServerRichText. useStoryblokServerRichText accepts the same options as useStoryblokRichText, and you import it from @storyblok/react/rsc.
Utility helpers
Section titled “Utility helpers”The React SDK also exports the core rich text utilities from @storyblok/richtext. The utilities are useful when implementing advanced custom components, such as custom image or table rendering.
Available utilities include:
renderRichText: The core rich text rendering function.buildStoryblokImage: Generates optimized Storyblok Image Service URLs.splitTableRows: Splits table rows intoheaderRowsandbodyRows.
Previous versions
Section titled “Previous versions”Was this page helpful?
This site uses reCAPTCHA and Google's Privacy Policy (opens in a new window).Terms of Service (opens in a new window) apply.
Get in touch with the Storyblok community