Storyblok
Search Storyblok's Documentation
  1. Content Modeling in React

Content Modeling in React

Content Modeling in React

Learn how to handle different content type blocks, render rich text, and use story references to manage content globally.

Setup

If you don’t want to make any editorial changes in your space, just copy this space in which we provide exactly the intended structure for you to follow this guide. Make sure to update the access token to the one from this space.

Alternatively, in your existing space, create a new content type block article and an “Articles” folder with content. The article content type block should have the following fields:

  • title: Text
  • content: Rich text

Learn more about fields in the concept.

Also, create an article-overview content type block and create it as the root story of the “Articles” folder. This block requires no fields.

Finally, create a featured-articles nestable block with the following field:

  • articles: References

Add a new featured-articles block to the body field of the home story and select some articles to be featured.

Fetch and list all articles

Create a new storyblok/ArticleOverview.jsx file to get all stories from this new content type.

storyblok/ArticleOverview.jsx
import { useStoryblokApi } from '@storyblok/react';
import { use, Suspense, useMemo } from 'react';
import { Link } from 'react-router';

export default function ArticleOverview() {
  const storyblokApi = useStoryblokApi();
  const articlesPromise = useMemo(() => {
    return storyblokApi.getAll('cdn/stories', {
      version: 'draft',
      starts_with: 'articles',
      content_type: 'article',
    });
  }, [storyblokApi]);

  return (
    <section>
      <h2>Articles</h2>
      <Suspense fallback={<p>Loading...</p>}>
        <ul>
          <ArticleList getArticles={articlesPromise} />
        </ul>
      </Suspense>
    </section>
  );
}

export function ArticleList({ getArticles }) {
  const articles = use(getArticles);

  return articles.map((article) => (
    <li key={article.uuid}>
      <Link to={`/${article.full_slug}`}>{article.name}</Link>
    </li>
  ));
}

Using the starts_with parameter, only stories from the “Articles” folder are fetched. Using the content_type parameter, the results are restricted to stories of the content type article.

Learn more about parameters and filter queries in the Content Delivery API documentation.

Now, the article overview page shows a list of links to all articles.

Create the article block

Add a new src/storyblok/Article.jsx component to render the new article content type.

src/storyblok/Article.jsx
import { storyblokEditable, StoryblokRichText } from '@storyblok/react';

export default function Article({ blok }) {
  return (
    <div {...storyblokEditable(blok)} className="article">
      <h1>{blok.title}</h1>
      <StoryblokRichText doc={blok.content} />
    </div>
  );
}

To render rich text fields, use the StoryblokRichText component provided by the @storyblok/react module.

<aside> 💡

Learn more about handling rich text in Storyblok in the fields concept and the @storyblok/richtext reference.

</aside>


When clicking on links present in the article overview page, an article page renders correctly.

Handle referenced stories

In the src/App.jsx data file, set the resolve_relations parameter to get the full object response of referenced stories.

src/App.jsx
import { StoryblokComponent, useStoryblok } from '@storyblok/react';
import { useParams } from 'react-router';

export default function App() {
  const { '*': slug } = useParams();
  const story = useStoryblok(slug || "home", {
    version: 'draft',
    resolve_relations: 'featured_articles.articles',
  });

  if (!story?.content) {
    return <div>Loading...</div>;
  }

  return <StoryblokComponent blok={story.content} />;
}

Learn more in the references concept documentation.

Next, create a new storyblok/FeaturedArticles.jsx component.

src/storyblok/FeaturedArticles.jsx
import { storyblokEditable } from '@storyblok/react';
import { Link } from 'react-router';

export default function FeaturedArticles({ blok }) {
  return (
    <section {...storyblokEditable(blok)} className="featured-articles">
      <h2>Featured Articles</h2>
      <ul>
        {blok.articles.map((article) => (
          <li key={article.uuid}>
            <Link to={`/${article.full_slug}`}>{article.name}</Link>
          </li>
        ))}
      </ul>
    </section>
  );
}

Now, this component will render links to the featured articles in the home page of your project.