---
title: @storyblok/react (Version 6.x)
description: @storyblok/react is Storyblok's official SDK for React applications.
url: https://www.storyblok.com/docs/libraries/js/react-sdk
---

# @storyblok/react (Version 6.x)

[@storyblok/react](https://github.com/storyblok/monoblok/tree/main/packages/react) is Storyblok’s official SDK for React applications.

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

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

```bash
npm install @storyblok/react@latest
```

## Usage

| Export | When to use | How to use |
| --- | --- | --- |
| `@storyblok/react` | Client-rendered apps and SPAs. | Use **`useStoryblok`** and **`StoryblokComponent`**. |
| `@storyblok/react/ssr` | Prerendering, and static export (including Next.js **`output: 'export'`**). Live editing is not supported. | Use **`StoryblokServerStory`** for rendering components. The bridge is not loaded. |
| `@storyblok/react/rsc` | Next.js App Router and other RSC setups. | Use **`StoryblokStory`** in server components so the bridge and live editing work in the visual editor. Use **`StoryblokServerComponent`** for nested blocks and **`StoryblokComponent`** in client components. |

### Configuration

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

src/main.jsx

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

> [!TIP]
> Learn how to retrieve an access token in the [access tokens concept](/docs/concepts/access-tokens).

> [!WARNING]
> The `region` parameter must be specified unless the space was created in the EU. Learn more in the [@storyblok/js reference](/docs/libraries/js/js-sdk).

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

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

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

### Fetching and rendering

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

src/App.jsx

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

## API

### `storyblokInit`

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

```js
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](/docs/libraries/js/js-sdk) 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`.

```js
import { storyblokInit, apiPlugin } from "@storyblok/react";

storyblokInit({ use: [apiPlugin] });
```

See the [@storyblok/js reference](/docs/libraries/js/js-sdk) for further details.

### `useStoryblok`

Enable both data fetching and bridge capabilities using this function.

```js
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](https://github.com/storyblok/monoblok/tree/main/packages/js-client). For the `BRIDGE_OPTIONS`, see the [@storyblok/preview-bridge reference](/docs/libraries/js/preview-bridge).

### `useStoryblokApi`

`useStoryblokApi()` returns the client instantiated in the application.

```js
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](https://github.com/storyblok/monoblok/tree/main/packages/js-client).

### `getStoryblokApi`

`getStoryblokApi()` is an alias of `useStoryblokApi()`.

### `useStoryblokBridge`

`useStoryblokBridge()` activates the Storyblok Bridge.

```js
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](/docs/libraries/js/preview-bridge).

It is possible to access the Storyblok Bridge via `window` instead of using `useStoryblokBridge` as shown below:

```js
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.

```js
loadStoryblokBridge();
```

### `useStoryblokState`

`useStoryblokState()` accepts a story from the Storyblok API and makes it reactive for live editing.

```js
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.

```jsx
<StoryblokStory story={STORY_OBJECT} bridgeOptions={BRIDGE_OPTIONS} />
```

For the `BRIDGE_OPTIONS`, see the [@storyblok/preview-bridge reference](/docs/libraries/js/preview-bridge).

### `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.

```jsx
<StoryblokComponent blok={blok} />
```

Use it to iterate over blocks fields as follows:

```jsx
{
  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 reference](/docs/libraries/js/js-sdk) for further details.

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

### `setComponents`

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

```js
setComponents(COMPONENTS_OBJECT);
```

### `StoryblokRichText`

Used to render a rich text field from a Storyblok story.

```tsx
<StoryblokRichText document={blok.richtext_field} />
```

The component accepts the following optional props:

-   `components`: Allows custom React components to be provided for supported rich text nodes and marks.
-   `optimizeImage`: Allows image optimization options to be configured for image nodes.

> [!TIP]
> When using TypeScript, custom components are fully type-safe through the `SbReactRichTextProps<T>` utility type. For example, `SbReactRichTextProps<"link">` provides the attributes and `children` available for the `link` mark, while `SbReactRichTextProps<"heading">` provides access to heading-specific attributes such as `level`.

See the [@storyblok/richtext reference](/docs/libraries/js/rich-text) for a complete list of supported nodes, marks, and customization options.

#### Custom components

Custom components can be registered using the `components` prop. The key must match a supported rich text node or mark name.

```tsx
import type { SbReactRichTextComponentMap } from "@storyblok/react";

const components: SbReactRichTextComponentMap = {
  heading: CustomHeading,
  link: CustomLink,
  table: CustomTable,
  bold: ({ children }) => <b className="font-bold text-black">{children}</b>,
};
```

The components can then be passed to `StoryblokRichText`:

```tsx
<StoryblokRichText document={blok.richtext_field} components={components} />
```

#### Example: Custom link component (mark)

Marks receive their rendered child content through the `children` prop.

```tsx
import type { SbReactRichTextProps } from "@storyblok/react";
import Link from "next/link";

export function CustomLink({ children, attrs }: SbReactRichTextProps<"link">) {
  return (
    <Link href={attrs?.href ?? ""} target={attrs?.target ?? "_self"}>
      {children}
    </Link>
  );
}
```

#### Example: Custom heading component (node)

Nodes can use the `children` prop to render child content.

```tsx
import type { SbReactRichTextProps } from "@storyblok/react";

export function CustomHeading({ children, attrs }: SbReactRichTextProps<"heading">) {
  const Tag = `h${attrs?.level ?? 1}` as keyof JSX.IntrinsicElements;

  return <Tag className="custom-heading">{children}</Tag>;
}
```

#### Example: Custom table component (advanced node)

For advanced use cases, nodes can access `content` and `context` to recursively render child nodes using `StoryblokRichText`.

The `splitTableRows` utility can be used to separate table header rows from body rows when creating custom table components.

```tsx
import { StoryblokRichText, splitTableRows, type SbReactRichTextProps } from "@storyblok/react";

export function CustomTable({ content, context }: SbReactRichTextProps<"table">) {
  const { headerRows, bodyRows } = splitTableRows(content);

  return (
    <table className="custom-table">
      {headerRows && (
        <thead>
          <StoryblokRichText document={headerRows} {...context} />
        </thead>
      )}

      <tbody>
        <StoryblokRichText document={bodyRows} {...context} />
      </tbody>
    </table>
  );
}
```

### `StoryblokServerRichText`

`StoryblokServerRichText` should be used instead of `StoryblokRichText` when working with React Server Components.

It provides the same API as `StoryblokRichText`, including support for the `components` and `optimizeImage` props.

### `useStoryblokRichText`

`useStoryblokRichText` can be used to programmatically render rich text content.

```tsx
import { useStoryblokRichText, type SbReactRichTextComponentMap } from "@storyblok/react";
import CustomLink from "./CustomLink";

const components: SbReactRichTextComponentMap = {
  link: CustomLink,
};

function App() {
  const render = useStoryblokRichText({ components });

  const richText = render(blok.articleContent);

  return richText;
}
```

It accepts the same configuration options as `StoryblokRichText`, including `components` and `optimizeImage`.

### Utility helpers

The React SDK also exports the core rich text utilities from `@storyblok/richtext`. These can be 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 into `headerRows` and `bodyRows`.

[Repository Playground](https://github.com/storyblok/monoblok/tree/main/packages/react/playground)See the repository playground for additional examples.

[React Guide](/docs/guides/react/)See the React guide for a comprehensive walkthrough on integrating Storyblok with React.

[Next.js Guide](/docs/guides/nextjs/)See the Next.js guide for a comprehensive walkthrough on integrating Storyblok with Next.js.

[Space Blueprint: React](https://github.com/storyblok/blueprint-core-react)See the core space blueprint for React to kickstart a new project.

[Space Blueprint: Next.js](https://github.com/storyblok/blueprint-core-nextjs)See the core space blueprint for Next.js to kickstart a new project.

## Previous versions

[@storyblok/react (Version 5.x)](/docs/libraries/js/react-sdk/v5)

## Pagination

-   [Previous: JavaScript SDK](/docs/libraries/js/js-sdk)
-   [Next: Astro SDK](/docs/libraries/js/astro-sdk)
