Contentful CMS - React Fundamental Project is a hands-on learning application integrating the Contentful headless CMS with a modern React frontend. This project demonstrates fetching and displaying dynamic content (such as projects) from Contentful using a custom React hook, and showcases best practices in component structure, API integration, and environment variable management.
- Live-Demo: https://contentful-cms-arnob.netlify.app/
- Project Summary
- Features
- Technology Stack
- Project Structure
- Installation and Setup
- Contentful Setup
- Environment Variables
- Fetching Data & Custom Hook
- Components Overview
- API Example
- Styling
- Learning Outcomes
- Keywords
- References & Resources
- Conclusion
- Hero Section: Eye-catching introduction with project summary and visuals.
- Projects Section: Dynamic list of projects fetched from Contentful CMS.
- Contentful Integration: Real-world usage of a headless CMS for content management.
- Custom Data Fetching Hook: Clean separation of data logic using React hooks.
- Modern UI: Responsive and visually appealing interface using SVG/PNG assets.
- Environment Variables: Secure API key management using
.env
files.
- React (Vite + JSX)
- Contentful (Headless CMS)
- JavaScript (ES6)
- CSS (custom and/or frameworks)
- Node.js/NPM
- Vite (for fast development server)
- contentful npm package
├── .DS_Store
├── .gitignore
├── Contentful.fig
├── README.md
├── index.html
├── package.json
├── package-lock.json
├── vite.config.js
├── public/
├── src/
│ ├── App.jsx
│ ├── Hero.jsx
│ ├── Projects.jsx
│ ├── data.js
│ ├── fetchProjects.jsx
│ ├── index.css
│ ├── main.jsx
│ └── assets/
Key files:
src/App.jsx
: Main app entry, renders Hero and Projects.src/Hero.jsx
: Hero/banner component.src/Projects.jsx
: Projects list, fetches from Contentful.src/fetchProjects.jsx
: Custom React hook for API calls.src/data.js
: Sample static data (for fallback/demo).src/index.css
: Styles.src/main.jsx
: React DOM entry point.
-
Clone the repository:
git clone https://github.com/arnobt78/Contentful-CMS--React-Fundamental-Project-18.git cd Contentful-CMS--React-Fundamental-Project-18
-
Install dependencies:
npm install
-
Set up environment variables (see Environment Variables)
-
Run the development server:
npm run dev
-
Visit
http://localhost:5173
(or as indicated in terminal).
- Sign up / log in to Contentful.
- Create a new Space.
- Add a Content Type named
cmsReactProject
(orprojects
):- Fields:
title
(Text),url
(Text),image
(Media)
- Fields:
- Add entries to the Content Type with your project data.
- API Access:
- Go to Settings > API keys.
- Get your Space ID and Content Delivery API - access token.
- Create a
.env
file in the root:VITE_API_KEY=your_contentful_access_token
Do NOT commit your real API key to version control!
The data fetching logic is encapsulated in a custom React hook located at src/fetchProjects.jsx
. It handles loading states, error handling, and parsing of Contentful API responses.
import { useEffect, useState } from "react";
import { createClient } from "contentful";
const client = createClient({
space: "your_space_id",
environment: "master",
accessToken: import.meta.env.VITE_API_KEY,
});
const useFetchProjects = () => {
const [loading, setLoading] = useState(true);
const [projects, setProjects] = useState([]);
useEffect(() => {
client.getEntries({ content_type: "cmsReactProject" })
.then((response) => {
const items = response.items.map((item) => ({
id: item.sys.id,
title: item.fields.title,
url: item.fields.url,
image: item.fields.image?.fields?.file?.url,
}));
setProjects(items);
setLoading(false);
})
.catch(() => setLoading(false));
}, []);
return { loading, projects };
};
export default useFetchProjects;
- App.jsx: Main component, imports Hero and Projects.
- Hero.jsx: Displays project title, description, and hero image.
- Projects.jsx: Uses
useFetchProjects
to fetch and render project cards. - data.js: Contains example static data (useful for fallback/demo).
- assets/: Place for images and SVGs used in the UI.
Example code to fetch entries directly from Contentful:
import { createClient } from "contentful";
const client = createClient({
space: "your_space_id",
environment: "master", // defaults to 'master'
accessToken: import.meta.env.VITE_API_KEY,
});
client
.getEntries({ content_type: "cmsReactProject" })
.then((response) => console.log(response.items))
.catch(console.error);
- Styling is managed in
src/index.css
. - Modify or extend this file to change the UI.
- Understand headless CMS concepts and benefits (content separated from presentation).
- Integrate Contentful with React for dynamic, CMS-driven sites.
- Use React hooks for clean data fetching and state management.
- Handle environment variables securely in modern JS projects.
- Structure React projects for scalability and clarity.
- Deploy React apps (example: Netlify).
react
contentful
headless cms
vite
custom hook
api integration
env variables
frontend
projects
javascript
learning
cms integration
dynamic content
- Contentful
- React Documentation
- Undraw (SVG/PNG images)
- Vite
This project provides a practical example of integrating a headless CMS with a React frontend, suitable for both learning and as a boilerplate for real-world applications. Use this template to quickly build portfolio/project sites powered by Contentful and React.
Feel free to explore, modify, and extend the code to suit your learning goals or project requirements!