Skip to content

@storyblok/react

@storyblok/react is Storyblok’s official development for React applications.

  • React version 17 or later
  • Node.js LTS (version 22.x recommended)
  • Modern web browser (e.g., Chrome, Firefox, Safari, Edge – latest versions)

Add the package to a project by running this command in the terminal:

Terminal window
npm install @storyblok/react@latest

Import and initialize the SDK using the access token of a Storyblok space.

src/main.jsx
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,
},
});

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).

src/storyblok/Page.jsx
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>;
}

Use the client to fetch a story and render the content using StoryblokComponent.

src/App.jsx
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} />;
}

This SDK provides a special module for React Server Components (RSC). Always import from @storyblok/react/rsc while using Server Components.

Import and initialize the SDK to access and configure all features.

import { storyblokInit } from '@storyblok/react';
storyblokInit(OPTIONS);`;
export const apiComponents = `storyblok({
components: {
page: 'storyblok/Page',
feature: 'storyblok/Feature',
grid: 'storyblok/Grid',
teaser: 'storyblok/Teaser',
},
});

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:

KeyDescriptionType
componentsAn object that maps React components to Storyblok blocks. Each component receives a blok prop containing the content of the block.object
enableFallbackComponentEnable or disable a fallback component to be rendered if no React component has been defined for a Storyblok block. Disabled by default.boolean
customFallbackComponentRegister a custom fallback component. Requires enableFallbackComponent to be enabled.React component

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.

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() returns the client instantiated in the application.

import { useStoryblok } from '@storyblok/react';
export default function App() {
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get(URL, API_OPTIONS)
}

For the API_OPTIONS, see the storyblok-js-client reference.

getStoryblokApi() is an alias of useStoryblokApi().

useStoryblokBridge() activates the Storyblok Bridge.

import { useStoryblok } from '@storyblok/react';
export default function App() {
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get(URL, API_OPTIONS)
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() is an alias of useStoryblokBridge().

Activates the Storyblok Bridge on the window.

loadStoryblokBridge();

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 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}" />`; export const apiStoryblokComponent1 = `<StoryblokComponent blok="{blok}" />`;
export const apiStoryblokComponent2 = `{ blok.nested_bloks?.map((currentBlok, index) => (
<StoryblokComponent blok="{currentBlok}" key="{currentBlok._uid" || index} />
)); }

For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.

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} />);
}

Use StoryblokServerComponent rather than StoryblokComponent when using React Server Components.

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() updates the component map of the current client instance.

setComponents(COMPONENTS_OBJECT);

Used to render a rich text field from a story.

<StoryblokRichText doc="{blok.richtext_field}" />

See the @storyblok/richtext reference for further details.

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>
);
}

Use StoryblokServerRichText rather than StoryblokRichText when using React Server Components.

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.