Using Contentful as a Blog Section in React Like a Pro : A Step-by-Step Guide

CodeIndicaCodeIndica
5 min read

Introduction

Recently, while developing a website, I encountered challenges with integrating Contentful. The documentation was not helpful, so I decided to write this article to provide a clearer guide. Contentful is a popular headless CMS that allows you to manage and deliver content across various platforms. When working with React, Contentful offers a flexible and efficient way to handle content without being tied to a traditional CMS. However, many developers face challenges with outdated or confusing documentation. This guide aims to provide a clear, step-by-step approach to integrating Contentful with a React application.

aijobster.work — React WebApp

Contentful is a popular headless CMS that allows you to manage and deliver content across various platforms. When working with React, Contentful provides a flexible and efficient way to handle content without being tied to a traditional CMS.

However, many developers face challenges with outdated or confusing documentation. This guide aims to provide a clear, step-by-step approach to integrating Contentful with a React application.

Prerequisites

Before we start, make sure you have the following:

  • Basic knowledge of React and JavaScript.

  • Node.js and npm installed on your machine.

  • An account on Contentful.

Step 1: Setting Up the Contentful Space

Sign Up/Log In to Contentful

Head over to Contentful and sign up for an account or log in if you already have one.

Create a New Space

Once logged in, navigate to your dashboard and create a new space. This space will hold your content models and entries.

Create Content Types

In your new space, define the structure of your content by creating content types. For this tutorial, let’s create a content type called “Blog Post” with the following fields:

  • Title (Short text)

  • Body (Long text)

  • Image (Media)

Add Content

Add some sample entries to your content types. These entries will be the data we fetch and display in our React application.

Step 2: Setting Up a React Project

Initialize a React App

Open your terminal and run the following command to create a new React app:

npx create-react-app contentful-react-app
cd contentful-react-app

Install Contentful SDK

Install the Contentful JavaScript SDK using npm:

npm install contentful

Step 3: Connecting to Contentful

Create a Contentful Client

Create a new file named contentfulClient.js in the src directory and add the following code:

import { createClient } from 'contentful';
const client = createClient({
  space: 'YOUR_SPACE_ID',
  accessToken: 'YOUR_ACCESS_TOKEN',
});export default client;

Replace YOUR_SPACE_ID and YOUR_ACCESS_TOKEN with your actual Contentful space ID and access token. These can be found in the Contentful dashboard under API keys.

Install other dependencies to render the content

npm install @contentful/rich-text-react-renderer @contentful/rich-text-types

Add the following code in Blog.tsx

import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import Banner from "../CommonComponents/Banner";
import Footer from "../CommonComponents/Footer";
import { fetchContent, Content } from "./ContentfulService";
import { documentToReactComponents } from "@contentful/rich-text-react-renderer";
import { BLOCKS, MARKS } from '@contentful/rich-text-types';
import { FiArrowLeft } from "react-icons/fi";

const BlogDetails: React.FC = () => {
  const { heading } = useParams<{ heading?: string }>();
  const decodedHeading = heading || "";
  const [blogContent, setBlogContent] = useState<Content | null>(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const data = await fetchContent();
        const selectedBlog = data.find(
          (content) => content.fields.headline === decodeURIComponent(decodedHeading)
        );
        setBlogContent(selectedBlog || null);
      } catch (error) {
        console.error("Error fetching content:", error);
      }
    };
    fetchData();
  }, [decodedHeading]);


  return (
    <div className="mt">
      <Banner title={blogContent !== null ?blogContent.fields.headline: 'Blog'} />
      <div className="page">
      <div className="container bg-white">
        <a href={"/blog"} className="py-3 d-flex align-items-center">
            <FiArrowLeft className="me-2" />Blogs
          </a>
        {blogContent && (
          <div>
            <h2 className="fw-bold">{blogContent.fields.headline}</h2>
            {documentToReactComponents(blogContent.fields.content, options)}
          </div>
        )}
      </div>
      </div>
      <Footer showFilter />
    </div>
  );
};

export default BlogDetails;

Create a Data Fetching Function

In the same contentfulClient.js file, add a function to fetch data:

export const fetchEntries = async () => {
  try {
    const entries = await client.getEntries();
    return entries.items;
  } catch (error) {
    console.error('Error fetching entries:', error);
  }
};

Fetch Data in a React Component

import { createClient, Entry } from 'contentful';
import { Document } from '@contentful/rich-text-types';

export interface Content {
  sys: {
    id: string;
    updatedAt: string;
  };
  fields: {
    headline: string;
    content: Document;
  };
}

const space = process.env.REACT_APP_CONTENTFUL_SPACE_ID;
const accessToken = process.env.REACT_APP_CONTENTFUL_ACCESS_TOKEN;

if (!space || !accessToken) {
  throw new Error('Contentful space ID and access token must be provided.');
}

const client = createClient({
  space,
  accessToken
});

export const fetchContent = async (): Promise<Content[]> => {
  try {
    const response = await client.getEntries();
    const content = response.items.map((item: Entry<any>) => ({
      sys: item.sys,
      fields: item.fields as Content['fields'] 
    }));
    return content;
  } catch (error) {
    console.error('Error fetching content:', error);
    throw error;
  }
};

Step 6: Styling and Enhancements

Styling

Add some CSS to style your components as desired. You can use plain CSS, Sass, or any CSS-in-JS solution.

Error Handling

Enhance your data fetching function to handle errors more gracefully and display a user-friendly message if something goes wrong.

Pagination

If you have a lot of data, consider implementing pagination. Contentful’s API supports querying with limits and offsets to fetch data in chunks.

Conclusion

In this guide, we covered how to integrate Contentful with a React application, from setting up Contentful to fetching and displaying content. Contentful’s flexibility and React’s power make a great combination for building modern web applications.

Feel free to leave comments and ask questions. Happy coding!

0
Subscribe to my newsletter

Read articles from CodeIndica directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

CodeIndica
CodeIndica

I am an avid Writer, great designer and awesome frontend developer.