Looking for ways to integrate Decoupled Drupal with React? Here is a complete guide that you must check and integrate both technologies effectively. So, let’s dive in and check the content of this post:

Disconnected Architecture

We must first comprehend what “coupled” means to comprehend the term “Decoupled.” A linked CMS connects the front- and back-ends. It is also referred to as “traditional” or “monolithic.” Developers and content managers use the same application, so while consumers engage with the front end, developers are making changes to the back end. Nevertheless, they are both using, seeing, and experiencing the same system.

The front end and back end of a decoupled CMS are distinct from one another. A delivery system manages the front end, while the CMS manages the back end. An application programming interface (API) links the two for publication.

Overview of Drupal & React

React JavaScript

A JavaScript package called React is used to create user interfaces. React was founded in 2013 and has gained a lot of traction since then because of its declarative design and lack of presumptions about your technological stack. Around React, a sizable ecosystem has developed in recent years. This includes conferences, excellent frameworks, and a rise in the need for React developers.

Drupal

Drupal is an open-source content management system that comes with a full toolkit for creating custom application logic, modeling data, and putting editing workflows in place. It’s a wonderful solution for the backend of your React application because it also has great support for JSON API or GraphQL web services.

To grasp some background knowledge and begin integrating React and Drupal, we will be creating a fully decoupled, basic listing website in this tutorial. We are going to construct a website listing travel destinations.

Let’s take a quick look at the steps we will take to construct this completely decoupled application:

  • Set up Drupal to provide data.
  • Make a React application.
  • What React Components Are
  • Retrieve Information and Show It

Step 1: Set up Drupal to provide data.

First, we must construct the content architecture, set up our backend (Drupal), and then make this data available as a web service API.

1. Use Composer to set up Drupal

Drupal setup has never been simpler, especially with Composer. For those who are unfamiliar, Composer is a PHP dependency manager that can be used to download Drupal along with all of its dependencies, as well as Drupal-contributed projects (modules, themes, etc.).

2. Set up Drupal

We must construct the database that Drupal will use and the matching user with all access to that database before installing Drupal. There are two ways to install Drupal: one is through the interactive user interface that Drupal provides by default.

3. Download and Set Up the Necessary Modules

Similar to plugins, Drupal modules expand the fundamental functionality of Drupal. The JSON API module must now be added. To achieve this, use Composer to download and enable the module. For even quicker navigation, let’s also download the Admin Toolbar module.

4. Provide an example of the content type and some

A certain sort of content is referred to as a Drupal “content type.” Drupal is pre-installed with the “Article” and “Basic Page” content types. You may easily create your content kinds with Drupal. We’re going to develop a Destination content type in this instance.

5. Examine API for JSON web services.

The next stage is to configure Drupal’s API data for React. The JSON API module was already activated in the previous third step. This module’s elegance lies in:

The JSON API module works immediately after it is enabled; no configuration is needed.

Drupal entities are made available as a web service API via this module.

Step2: Make a React App

After the necessary data is exposed by the JSON API, we can proceed to configure our front end to utilize and show the data in the application. There are several methods for creating a new ReactJS project and configuring it to meet our needs. We will be using Facebook’s create-react-app in this example. As a result, we can develop React apps without requiring any build settings.

Launch the terminal and navigate to the project’s root directory, travel_destinations. Here, we will install create-react-app in a new directory called “react_app.” Make sure you have installed NodeJS version 6 or higher.

This page is essentially generated by the scaffold files created by the Create React App. The public and src directories are located in the files produced by the app inside the react_app directory, if we examine them closely. The index.html file and public assets are located in the “public” folder, and the index.js file in the “src” directory renders the React application onto your website.

React Elements

In recent years, the majority of web development has been based on the conventional top-down design that is offered by page and screen. These designs are broken down into elements, grids, and containers for processing. The way Drupal core functions is also comparable. There has been a change in strategy in the last few days, with an emphasis on the discrete components that come together to form the user interface. This is comparable to an object-oriented design in which an object is likened to an actual thing with certain characteristics and actions. The React Component is comparable. Starting at the “atomic” level and working their way up to collections of atoms, layouts, and screens, developers create reusable components. According to official React documentation:

Props

When we think of a button as a component, we also give it a label to display an HTML button. In this way, a component is similar to a container that is ultimately there to produce some output based on some input. Now, if we are building reusable components, our method should produce results that are in line with our specifications, which we provide as inputs in the form of props.

State

A component’s state can be characterized as an attribute that establishes a specific condition for the component and aids in monitoring and modifying its behavior. An accordion, for instance, can have an open or closed condition. Accordion, then, is this component over here, and status is a state. You may think of the Heading and Description as accessories for a reusable Accordion part.

Step 3: Explain React Elements

An essential part of preparing for your React application is defining components. As was previously said, a React Application is just a nested React Component that contains another React component. Additionally, HTML is used to render this top-level component.

As we construct the Travel Destinations Listing Application, we are essentially displaying Destination Items, which are React vocabulary’s equivalent of atomic-level elements or components. The fundamental component of our app is the destination list, which is created when multiple destination items are joined.

Here is a summary of the React components that make up our application:

DestinationList — — — DestinationItem — App

Analyzing the fact that the app is a React component is crucial. Let’s get to work developing our application. Make a Components directory under react_app > src. In the destination directory, let’s further categorize components connected to destinations. Thus, we define the DestinationItem component in react_app > src > Components > Destination.

Step 4: Fetch Data & Display

The next step is to take our Drupal JSON API response, retrieve it, and use our components to show it. To display data at the end, we will play around with state and props and utilize the retrieve API that native JavaScript provides. We’re going to get closer to ReactJS by learning more about state and props and how they’re used.

1. Retrieve Information

The idea is that when the ‘App’ react component is initialized, we will retrieve the URL and set it in the state of the app. Then, if the state is altered, the component will be re-rendered. We are unable to directly alter the state. Rather, we use the setState function to update the state. To start everything off, we’ll use the single lifecycle method “componentWillMount,” which is called just once, right before the first render.

Add a constructor in App.js as follows:

constructor() {

  super();

  this.state = { data: null };

  this.loadDestinations = this.loadDestinations.bind(this);

  this.updateData = this.updateData.bind(this);

}

In this case, state is being defined, and data is being set to null under state. We tie the “this” (App component) function to the two additional functions we define, loadDestinations and updateData. The Drupal API will be accessed to retrieve data via the loadDestinations method.

Besides import declarations, define a constant LIST_URL as

const LIST_URL = ‘http://td-drupal.local:80/jsonapi/node/destination’;

Additionally, let’s add the loadDestinations method to the class App as:

loadDestinations() {

  // Fetch Destinations.

  fetch(LIST_URL, {mode:’cors’})

    .then(function (response) {

      return response.json();

    })

    .then((data) => this.updatedata(data)) 

    .catch(err => console.log(‘Fetching Destinations Failed’, err));

We submit the request with the URL and options first, then we wait for the server to respond before converting it to JSON. Next, we are using this data to call the updateData method. We capture any errors in the last line if the request fails.

Include the updateData function as well, which adds state info to the JSON data that was received.

 updateData(responseData) {

  this.setState({data: responseData.data});

}

This will make the component look better. Let’s include a lifecycle method to start the entire procedure.

componentWillMount() {

  this.loadDestinations();

}

It is now necessary to send this data as a prop to the DestinationList class. Update the render() method accordingly.

  return (

    <div className=”App”>

      <DestinationList

        data={this.state.data}

      />

    </div>

  );

}

2. Show Information

We send data to DestinationList in the same manner as in the previous phase. We now gather that data in the DestinationList class in the DestinationList.js file, and following a brief verification, we build an array of DestinationItems by passing the item.

Modify DestinationList’s render function as follows:

import React from ‘react’;

import DestinationItem from “./DestinationItem”;

export default class DestinationList extends React.Component {

render() {

  let { data } = this.props;

  return (

    <div>

      <h1>Here are your best Travel Destinations</h1>

      {data !== null &&

      data !== undefined &&

      data.length > 0 ?

        data.map(item => <DestinationItem {…item} key={item.id}/>)

:

        <div>No destinations found.</div>

}

</div>

);

}

}

Finally, we will use the item provided over here in the DestinationItem class to replace the placeholders produced earlier. Array.map function is used to deliver the entire item using {…item} to DestinationItem class as props and key as item.id. Modify the DestinationItem component’s render function as follows:

import React from ‘react’;

export default class DestinationItem extends React.Component {

render() {

  return (

    <div>

      <h2>{this.props.attributes.title}</h2>

      <div dangerouslySetInnerHTML={{__html: this.props.attributes.body.value}} />

    </div>

);

}

}

All of the array data is supplied as props to this class when we send {…item} from the DestinationList class to the DestinationItem class; as a result, we can access the title and body using this. commendable in this way. props.title & this.props.body.value; props. attributes.

You will see an issue when you refresh the page in the browser. As a result, even though we were expecting our data, the console error was generated. We anticipate a warning similar to the “No ‘Access-Control-Allow-Origin’ header is present on the requested resource Drupal,” which essentially prevents React Application from using JSON API data from a Drupal site due to various domains. Therefore, we must fix this on Drupal’s end. We can easily make the necessary changes with Drupal. All we have to do is update the services.yml file located in the web/sites/default directory of Drupal. To enable CORS (Cross-Site HTTP requests), we only need to copy default.services.yml as services.yml in the same directory if it isn’t already there.

Cors.config has been enabled: yes

# Indicate the authorized headers (such as ‘x-allowed-header’).Headers: [‘*’]

# Indicate the request methods that are permitted; enter [‘*’] to accept all options.

PermittedTechniques: [‘*’]

# Set up requests that are permitted from particular origins. Origins: [‘*’]

# Adjust the header for Access-Control-Expose-Headers.Headers: Accurate

# Configures the header for Access-Control-Max-Age. Age is accurate.

# Configures the header for Access-Control-Allow-Credentials.Qualifications: Accurate

Conclusion

The Headless/Decoupled Drupal is a step toward the current industry trend toward API-first architecture, the emergence of contemporary frontend tools to better serve the client, and the ability to leverage Drupal capabilities along with other potent architectures. It is currently difficult to develop a fully decoupled website due to the inadequate documentation for decoupled design using best practices and the difficulties of extracting data from some frequently used Drupal features, such as the paragraph module and layout builder. As Drupal founder Dries Buytaert also advises, choosing to go gradually detached right now is a preferable option.

Decoupled architecture presents several benefits and drawbacks; the choice should be made based on the desired outcome. Find out how Appic Softwares can help you navigate these seas and provide a customized solution that satisfies your particular requirements by connecting with us now!