Redux tutorial with Contentful

How to use Redux to manage application state and data-fetching logic in a React project, and how to apply these techniques to data coming from Contentful.
Published
April 7, 2023
Category

Guides

Redux is a state management library for JavaScript. It brought the concept of unidirectional data flow to the world of frontend development, and is used by a variety of mainstream apps. The library is written in plain JavaScript so it works with any framework, whether that’s Vue, Angular, Svelte, or no framework at all.

This tutorial will guide you through using Redux to manage application state and data-fetching logic in a React project and how to apply these techniques to data coming from Contentful. All the code in this tutorial can be found in this repository.

Prerequisites

To follow along, you’ll need:

  • A Contentful account. Sign up if you do not have one. 

  • Intermediate knowledge of JavaScript and familiarity with Redux.

  • Node.js version 18 or above.

Prepare your Contentful space: Creating a content model

Using your browser, navigate to your Contentful dashboard. Create a space, then create a content model to store your data. We’ll be building an example auction application.

This tutorial uses woodcraft_auction as the name of the content type. Feel free to use another name. 

Using your browser, navigate to your Contentful dashboard. Create a space, then create a content model to store your data. We’ll be building an example auction application.

Note: If you’re unfamiliar with Contentful, refer to our beginner’s guide.

Add the following fields to the woodcraft_auction content type: 

  • A short text field called name for storing the name of each item available to be auctioned.

  • A rich text field called description for describing the available item.

  • A date & time field called date_posted to specify an item’s posting date.

  • A media field for storing several images of the item. Ensure you select many files as the type of media field.

  • A number field type called price to specify the item’s costs.

Now, you have five fields within your content type.

Now, you have five fields within your content type.

Click the Save button at the top. This saves the fields you’ve added to the content type. 

Adding a sample content entry

Add a sample entry into the woodcraft_auction content type you created. This entry is the first data that the React application will fetch with Redux.

To add your first entry, switch to the Content Editor page of the Contentful dashboard. Next, click the Add Entry button and provide content for the name, description, date_posted, images, and price fields. Ensure you publish your content by clicking the Publish button.

Add a sample entry into the  woodcraft_auction content type you created. This entry is the first data that the React application will fetch with Redux.

Creating a Contentful Content Delivery API token

Next, you need to get an API key. The Contentful Content Delivery API (CDA) is a read-only API that allows you to fetch content you’ve stored within a Contentful space. Full instructions to create your own can be found here.

Building the Redux application 

You’re now ready to build your Redux application. You’ll start by creating a standalone React app following the steps below. 

Creating a React application

First, generate a React project called react-contentful-redux using the React template for Vite via the command-line interface.

npm create vite@latest react-contentful-redux -- --template react

Next, execute the two commands below. 

cd react-contentful-redux 

npm install @contentful/rich-text-react-renderer @reduxjs/toolkit react-redux

This navigates into the react-contentful-redux project and installs the dependencies necessary to build the project.

Finally, create a file called .env within the react-contentful-redux project directory. Use the file to store your Contentful credentials securely in the following format. Ensure you replace the placeholder values with their corresponding values from Contentful.

Now you can use the stored credentials in a client class to fetch data from Contentful. 

⚠️ Because this is a client-side application, your environment variables will be sent to the user’s browser. As a result, Vite requires us to add the VITE_ prefix to make us aware of this.

Creating a Contentful client

Create a ContentfulApiClient.js file within the React application’s src directory. The file contains all the logic for interacting with the Content Delivery API. We use a ContentfulClient class to keep the code clean and avoid duplicated API requests. 

Add the following code into the empty ContentfulApiClient.js file:

Adding Redux to the application

The Redux documentation recommends the Redux Toolkit (RTK) as the “official, opinionated, batteries-included toolset.” RTK includes many tools to work with Redux, like “thunks” for asynchronous operations, and many others. 

Start by creating a directory called state within the src directory. This stores all additional files you’ll make while building the slice and action for the application.

Creating a Redux action

Create a product.action.js file within the state directory to store the actions for the application. 

Add this code block below to the actions in the product.action.js file. This creates an instance of the ContentfulClient class and creates a thunk:

The callback method of the fetchArtworks thunk above invokes the getItems method. This fetches all the published entries within the project’s content type on Contentful. Furthermore, the createAsyncThunk method allows you to track the state of the network requests with minimal effort.

Next, create an RTK slice to place the data resolved from the fetchArtworks thunk into the Redux state. 

Creating a Redux slice 

Create a product.slice.js file within the state directory. Add the content of the next code block to the file. 

The slice above has an empty array of artworks as its initial state. After resolving the promise from the fetchArtworks thunk, the code sets the `artwork` property of the current state to the returned value. 

Creating a Redux store

After creating the reducer functions, we create the Redux store with `configureStore`. Then, we wrap the entire React application with the Provider from the react-redux package to give the children components access to the store.

Create a store.js file in the state directory. Build the Redux store by adding the following:

We make sure that devTools is only active when in development by passing an option to the configureStore() method.

Next, open the App.jsx file and replace the default boilerplate code with this:

The Redux part of the application is now set up and ready to use with the React components. 

Building the application components

The React application only uses two components: one for the banner section and the other to render a card.

To create the styles to be used by the HTML Banner and Card components, replace the default boilerplate code in ./src/App.css with the code below:

Open the index.css file and delete the boilerplate style rules, as you no longer need them.

In the next section, you will create a components directory within the existing src directory. This directory will store the files for the Banner and Card components.

Creating the Banner section

First, create a components directory, then create a Banner.jsx file inside it.

Next, add this code block to the file:

This displays the name and description of the service and a search field for customers to find available craftworks.

Creating the CraftCard

Now, create a Card.jsx file within the components directory. Add the content of the following code block into the file.

The data displayed within the Card component above is passed in as props from the parent component that renders it. The @contentful/rich-text-react-renderer package parses the Rich Text description. 

The component uses the getAsset method from the ContentfulClient class in a useEffect hook. This fetches the entry data and stores the image URL in its local state immediately after the component renders and the image prop has a value. 

Creating the Home page

In the src directory, create a Home directory containing an index.jsx file.   

The index.jsx file renders the Banner component, dispatches the fetchArtworks thunk, and then displays the Contentful entries stored within the Redux state using the Card component.

Using the Redux application

To start the server and access it from your web browser, execute this command:

npm run dev

Open the running react-contentful-redux application on http://localhost:5173/ in your web browser. View the default page that lists your Contentful entries.

Open the running react-contentful-redux application on http://localhost:5173/ in your web browser. View the default page that lists your Contentful entries. 

Your app made with Redux and Contentful.

Using the redux-devtools extension, you can view, monitor, mutate, and debug Redux operations from your browser. 

The image below shows the fetchArtworks action pending and then resolved alongside the state of the products reducer.

The image below shows the fetchArtworks action pending and then resolved alongside the state of the products reducer.

Wrapping up

Congratulations on completing this hands-on guide! As demonstrated, Redux provides a better way to distribute the data returned from Contentful without excessive props drilling. 

As you build your next React application to display your digital content stored within Contentful, consider using Redux to better manage the state of your application and its data-fetching logic.

Explore this React CMS resource guide for deeper insights into seamlessly integrating Contentful with React.

Start building

Use your favorite tech stack, language, and framework of your choice.

About the authors

Don't miss the latest

Get updates in your inbox
Discover new insights from the Contentful developer community each month.
add-circle arrow-right remove style-two-pin-marker subtract-circle remove