Storyblok
Search Storyblok's Documentation
  1. @storyblok/react

@storyblok/react

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

Practical resources

Requirements

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

Installation

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

npm install @storyblok/react@latest

Usage

Configuration

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

Learn how to retrieve an access token in the access tokens concept.

The region parameter must be specified unless the space was created in the EU. Learn more in the @storyblok/js package reference.

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.

src/storyblok/Feature.jsx
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";

const Page = ({ blok }) => (
  <section>
    {blok.body
      ? blok.body.map((blok) => (
          <StoryblokComponent blok={blok} key={blok._uid} />
        ))
      : null}
  </section>
);

export default Page;

Fetching and rendering

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

React Server Components

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

API

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

apiPlugin configures the implementation of the Storyblok API. It is imported from @storyblok/js.

import { storyblokInit, apiPlugin } from '@storyblok/react';

storyblokInit({ use: [apiPlugin] });

For more information, see the @storyblok/js package reference.

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 package reference. For the BRIDGE_OPTIONS, see the StoryblokBridge reference.

useStoryblokApi

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 package reference.

getStoryblokApi

getStoryblokApi() is an alias of useStoryblokApi().

useStoryblokBridge

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 StoryblokBridge 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

registerStoryblokBridge() is an alias of useStoryblokBridge().

loadStoryblokBridge

Activates the Storyblok Bridge on the window.

loadStoryblokBridge();

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

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

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

Use StoryblokServerComponent rather than StoryblokComponent when using React Server Components.

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 package reference for further details.

const Feature = ({ blok }) => {
	return (
		<section {...storyblokEditable(blok)} key={blok._uid}>
			{blok.title}
		</section>
	);
};

setComponents

setComponents() updates the component map of the current client instance.

setComponents(COMPONENTS_OBJECT);

StoryblokRichText

We have identified issues with richtext and Types on React 19 and Next.js 15. As a temporary measure, we advise you to continue using React 18 and Next.js 14 until we have fully resolved the issues.

Used to render a rich text field from a story.

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

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

See further options in the @storyblok/richtext package reference.

Example: Overriding default resolvers

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

useStoryblokRichText

We have identified issues with richtext and Types on React 19 and Next.js 15. As a temporary measure, we advise you to continue using React 18 and Next.js 14 until we have fully resolved the issues.

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 further options in the @storyblok/richtext package reference.

Further resources