Learn how to use React, Contentful, and Netlify by building a beach resort website

React has emerged as one of the most popular JavaScript libraries in recent years for building dynamic, component-based user interfaces. When combined with a headless CMS like Contentful for content management and a platform like Netlify that simplifies deployment, React provides a powerful toolset for modern web development.

In this guide, we‘ll walk through building a beach resort website to demonstrate how React, Contentful, and Netlify can work together in practice. By the end, you‘ll have a solid understanding of React fundamentals as well as hands-on experience with integrating a headless CMS and deploying a web app.

Why React, Contentful, and Netlify?

Before we dive into building our example application, let‘s briefly discuss what makes React, Contentful, and Netlify a compelling stack for web development.

React

React allows you to build user interfaces as a collection of reusable components, each with its own encapsulated state and rendering logic. This component-based architecture makes your UI code more modular and maintainable.

React utilizes a virtual DOM (Document Object Model) to declaratively describe what your UI should look like based on the current application state. When data changes, React efficiently determines what needs to be updated in the actual DOM, providing a fast and fluid user experience. Components can also react to events and update their state, re-rendering themselves and their children as needed.

Contentful

Contentful is a headless CMS that decouples content management from content presentation. You define your content types and structure using Contentful‘s web app, and then integrate that content into your website or application via Contentful‘s API.

This separation of concerns means that developers and content authors can work independently. Developers build the presentational frontend (in this case using React), while content authors manage the content itself in Contentful. Contentful‘s rich text editor and asset management also provide a user-friendly interface for content creation.

Netlify

Netlify is a platform for deploying and hosting modern web applications. You can connect a Git repository to Netlify, and every time you push changes, Netlify will automatically build and deploy your app. This simple workflow integrates continuous integration and deployment.

Netlify also provides features like a global CDN (content delivery network) for asset optimization, built-in SSL support, instant rollbacks to previous deployments, and integration with popular services like Slack and GitHub. You can even hook up custom domains and take advantage of split testing.

Setting up the project

With our stack decided, let‘s initialize a new React project using create-react-app:

npx create-react-app beach-resort
cd beach-resort
npm start

You should now have a basic working React application accessible at http://localhost:3000/. We‘ll use this as the starting point for our beach resort site.

Next, sign up for a free Contentful account at www.contentful.com. Once logged in, create a new empty space for this project.

From the Content model tab, add a new content type to represent the details of each room at the resort. For example:

Name: Room
Fields:
  - name (Short text)
  - slug (Short text)
  - description (Rich text) 
  - price (Number)
  - capacity (Number)
  - size (Number)
  - featured (Boolean)
  - images (Media, many)
  - extras (Short text, many)

Then click on the Content tab and add a few example room entries to populate your content.

To integrate this content into the React app, install the official Contentful JavaScript SDK:

npm install contentful

We‘ll fetch the room data from the Contentful API in our React components.

Displaying content in React components

First, create a configuration file called .env in the project root with your Contentful space ID and access token:

REACT_APP_API_SPACE=your-space-id
REACT_APP_API_TOKEN=your-access-token

Create a new file called contentful.js to initialize the Contentful client:

import { createClient } from ‘contentful‘;

export default createClient({
  space: process.env.REACT_APP_API_SPACE,
  accessToken: process.env.REACT_APP_API_TOKEN
});

Now, in a component, we can fetch entries from Contentful:

import React, { useState, useEffect } from ‘react‘;
import client from ‘./contentful‘;

const RoomsList = () => {
  const [rooms, setRooms] = useState([]);

  useEffect(() => {
    client.getEntries({ content_type: ‘room‘ })
      .then(response => setRooms(response.items))
      .catch(console.error);
  }, []);

  return (
    <div>
      {rooms.map(room => (
        <div key={room.sys.id}>
          <h2>{room.fields.name}</h2>
          <p>{room.fields.description}</p>
          <p>Price: {room.fields.price}</p>
        </div>
      ))}
    </div>
  );
};

export default RoomsList;

Here we‘re using the useEffect hook to fetch rooms from the Contentful API when the component mounts. Once the data is returned, we update component state using the useState hook. The JSX rendered by the component maps over the array of rooms and displays the details of each.

Client-side routing with React Router

To add client-side routing, first install the React Router library:

npm install react-router-dom 

Then update your main App component to define the routes:

import React from ‘react‘;
import { BrowserRouter as Router, Route, Switch } from ‘react-router-dom‘;
import HomePage from ‘./pages/HomePage‘;
import RoomsPage from ‘./pages/RoomsPage‘; 
import SingleRoomPage from ‘./pages/SingleRoomPage‘;

const App = () => {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={HomePage} />
        <Route exact path="/rooms/" component={RoomsPage} />
        <Route path="/rooms/:slug" component={SingleRoomPage} />
      </Switch>
    </Router>
  );
};

export default App;

Now you can create the route components (HomePage, RoomsPage, SingleRoomPage) that will be rendered when the user navigates to the corresponding path. The SingleRoomPage component would fetch an individual room entry based on the slug parameter.

Managing global state with React context

As your application grows, you may need to share state between multiple components. React‘s built-in context API provides a way to do this without resorting to prop drilling.

First, create a new context:

import React from ‘react‘;

const RoomContext = React.createContext();

export default RoomContext;

Then create a provider component that will wrap your application and provide data via the context:

import React, { useState } from ‘react‘;
import client from ‘./contentful‘;
import RoomContext from ‘./roomContext‘;

const RoomProvider = ({ children }) => {
  const [rooms, setRooms] = useState([]);
  const [featuredRooms, setFeaturedRooms] = useState([]);

  // fetch data from Contentful  
  useState(() => {
    client.getEntries({ content_type: ‘room‘ })
      .then(response => {
        const rooms = formatData(response.items);
        const featuredRooms = rooms.filter(room => room.featured);

        setRooms(rooms);
        setFeaturedRooms(featuredRooms);
      });
  }, []);

  return (
    <RoomContext.Provider value={{ rooms, featuredRooms }}>
      {children}
    </RoomContext.Provider>
  );
};

export default RoomProvider;

Now any component can access the rooms and featuredRooms data provided by this context:

import React, { useContext } from ‘react‘;
import RoomContext from ‘../roomContext‘;

const FeaturedRooms = () => {
  const { featuredRooms } = useContext(RoomContext);

  return (
    <div>
      {featuredRooms.map(room => (
        <div key={room.id}>{room.name}</div>  
      ))}
    </div>
  );
};

export default FeaturedRooms;

Deploying to Netlify

With the core features implemented, we‘re ready to deploy our beach resort site to the web using Netlify.

First, push your code to a new GitHub repository. Include a .netlify.toml configuration file in the project root:

[build]
  publish = "build"
  command = "npm run build"

Log in to Netlify and click "New site from Git". Connect your GitHub repository and Netlify will automatically detect the build settings from .netlify.toml.

Click "Show advanced" and add your Contentful space ID and access token to the build environment variables, so they‘re available at build time.

Once deployed, you‘ll have a live React application pulling content from Contentful. Whenever you push changes to GitHub, Netlify will automatically rebuild and redeploy the site.

Next steps

Congratulations, you now have a working beach resort website built with React, Contentful, and Netlify! As you continue developing your application, here are some additional features you may want to implement:

• Add search/filtering of rooms by price, size, capacity, etc.
• Create a room booking form that sends requests to Contentful
• Optimize images served from Contentful using Netlify‘s image transformation
• Implement pagination for room listings
• Incorporate user authentication for booking management

I‘ve posted the complete source code for this example project on GitHub. You can use this as a starting point and reference for your own projects.

To dive deeper into the topics covered, check out the following resources:

Official React tutorial
Contentful JavaScript tutorials
Step-by-step guide to deploying on Netlify
freeCodeCamp‘s coding tutorials

You can also find a full 6-hour video course on building this beach resort project on the freeCodeCamp.org YouTube channel.

Learning React, Contentful, and Netlify will put you in a great position to build modern, content-driven web applications. Feel free to leave any questions in the comments. Happy coding!

Similar Posts