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.
To follow along, you’ll need:
A Contentful account. Sign up if you do not have one.
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.
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
descriptionfor describing the available item.
A date & time field called
date_postedto 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
priceto specify the item’s costs.
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,
price fields. Ensure you publish your content by clicking the Publish button.
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.
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
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
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.
Creating a Redux action
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:
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
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.
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
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:
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.
index.jsx file renders the Banner component, dispatches the
fetchArtworks thunk, and then displays the Contentful entries stored within the Redux
state using the
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.
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
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.
Explore this React CMS resource guide for deeper insights into seamlessly integrating Contentful with React.