Announcing @storyblok/react

Contents
    Try Storyblok

    Storyblok is the first headless CMS that works for developers & marketers alike.

    Storyblok editing capabilities

    Starting from our brand new @storyblok/js, we announced @storyblok/svelte about 1 week and a few days ago.

    Today, we'd like to announce another hotūüĒ• SDK -¬†@storyblok/react¬†ūü•≥

    We reviewed how React & Storyblok projects are handled and took care of the pain points to deliver less complication.

    Let us know how's your DX with our new @storyblok/react SDK!

    Special thanks to¬†Alex,¬†Facundo,¬†and¬†Josefine¬†for their hard & awesome work ūüôŹ

    You'll need TL;DR? You can jump directly to the LIVE DEMO in Stackblitz right away.

    Usage

    First things first, install @storyblok/react by running the command below.

    npm install @storyblok/react
    // yarn add @storyblok/react

    Initialization

    The next step, register the plugin on your application and add the access token from your Storyblok space.

    HINT::

    i.e. You can do that in pages/_app.js if you use @storyblok/react for your Next.js projects, or in index.js file in React apps.

    If you would like to use the Storyblok API Client, you can add apiPlugin.

    index.js
    import { storyblokInit, apiPlugin } from "@storyblok/react";
    import Page from "./components/Page.jsx";
    import Teaser from "./components/Teaser.jsx";
    
    storyblokInit({
      accessToken: "YOUR_ACCESS_TOKEN",
      // bridge: true,
      use: [apiPlugin],
      components: {
        page: Page,
        teaser: Teaser,
      },
    });

    Did you realize something?ūüėé

    You don't have to handle conditionally returning components by yourself anymore!

    We took care of all and you just need to add all your components to the components object in the storyblokInit function, and that's it!

    Query Storyblok API and listen for Visual Editor changes

    You can use the convenient useStoryblok(slug, apiOptions) hook to get the story from the Storyblok CDN API, and automatically use Storyblok Bridge to listen for the Visual Editor live changes.

    App.js
    import { useStoryblok, StoryblokComponent } from "@storyblok/react";
    
    export default Home() {
      const story = useStoryblok("react", { version: "draft" });
    
      if (!story.content) {
        return <div>Loading...</div>;
      }
    
      return <StoryblokComponent blok={story.content} />;
    }

    Link your components to Storyblok Visual Editor

    For every React component, you want to link to its corresponding Storyblok component, you can use storyblokEditable function with the blok content where blok is the actual blok data coming from Storyblok's Content Delivery API

    components/Feature.js
    import { storyblokEditable } from "@storyblok/react";
    
    const Feature = ({ blok }) => {
      return (
        <div {...storyblokEditable(blok)}>
          <div>{blok.name}</div>
          <p>{blok.description}</p>
        </div>
      );
    };
    export default Feature;

    Then the¬†<StoryblokComponent blok={blok}¬†you saw before will take care of loading them for you ūüėČ.

    Next.js example:

    hint:

    TL;DR: Play with the Next.js https://stackblitz.com/edit/react-next-sdk-demo

    Since in Next.js you use the getStaticProps function to get the Page props, the useStoryblok hook has no use here.

    But no worries, you can use a combination of useStoryblokApi and useStoryblokState to achieve the same on Next.js and Gatsby! This is how the previous example looks in Next.js:

    index.js
    import { useStoryblokState, useStoryblokApi, StoryblokComponent } from "@storyblok/react";
    
    export default function Home({ story: initialStory }) {
      const story = useStoryblokState(initialStory);
    
      if (!story.content) {
        return <div>Loading...</div>;
      }
    
      return <StoryblokComponent blok={story.content} />;
    }
    
    
    export async function getStaticProps({ preview = false }) {
      const storyblokApi = useStoryblokApi()
      let { data } = await storyblokApi.get(`cdn/stories/react`, {
        version: "draft"
      });
    
      return {
        props: {
          story: data ? data.story : false,
          preview,
        },
        revalidate: 3600, // revalidate every hour
      };
    }

    Next Steps

    Want to contribute? You can create an issue or PR on the react repo or get in touch.

    Resource Link
    @storyblok/react docs https://www.npmjs.com/package/@storyblok/react
    Storyblok Learning Hub https://www.storyblok.com/docs
    DEV.to announcement blog post https://dev.to/storyblok/announcing-storyblokreact-pgn

    Developer Newsletter

    Want to stay on top of the latest news and updates in Storyblok?
    Subscribe to Code & Bloks - our headless newsletter.

    An error occurred. Please get in touch with marketing@storyblok.com

    Please select at least one option.

    Please enter a valid email address.

    This email address is already registered.

    Please Check Your Email!

    Almost there! To confirm your subscription, please click on the link in the email we’ve just sent you. If you didn’t receive the email check your ’junk folder’ or