---
title: @storyblok/react (Version 6.x)
description: @storyblok/react is Storyblok's official SDK for React applications.
url: https://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 story.

```jsx
<StoryblokRichText doc={blok.richtext_field} />
```

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

#### Example: Custom link with Next.js Link

Use `asTag` to render a Next.js `Link` component for internal story links:

```tsx
import { Mark } from "@tiptap/core";
import { asTag } from "@storyblok/react";
import Link from "next/link";

const CustomLink = Mark.create({
  name: "link",
  renderHTML({ HTMLAttributes }) {
    if (HTMLAttributes.linktype === "story") {
      return [asTag(Link), { href: HTMLAttributes.href }, 0];
    }
    return ["a", { href: HTMLAttributes.href, target: HTMLAttributes.target }, 0];
  },
});

function App() {
  return <StoryblokRichText doc={blok.richtext_field} tiptapExtensions={{ link: CustomLink }} />;
}
```

### `StoryblokServerRichText`

Use `StoryblokServerRichText` rather than `StoryblokRichText` when using React Server Components.

### `useStoryblokRichText`

Use this function to programmatically render a rich text field.

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

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

  const root = () => render(blok.articleContent);

  return <>{root()}</>;
}
```

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

#### Example: Custom tiptap extensions

```tsx
import Heading from "@tiptap/extension-heading";
import { useStoryblokRichText } from "@storyblok/react";

const CustomHeading = Heading.extend({
  renderHTML({ node, HTMLAttributes }) {
    const level = node.attrs.level;
    return [`h${level}`, { class: `heading-${level}`, ...HTMLAttributes }, 0];
  },
});

function App() {
  const { render } = useStoryblokRichText({
    tiptapExtensions: { heading: CustomHeading },
  });

  const root = () => render(blok.articleContent);

  return <>{root()}</>;
}
```

## Further resources

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