In my previous article “RESTful Web Services in Drupal 8: quick start guide” I just mentioned some possibilities that arise from a decoupled Drupal approach. One of them is an opportunity to build a Drupal site with separate back-end and front-end. Why headless Drupal became a trend in a few past years? First of all, it makes a developer’s life easier: back-end and front-end teams can work separately from each other. Another advantage is an ability to serve content on the growing numbers of websites, back-end systems, different types of applications and multiple devices, such as IoT devices, wearables and more. All of these abilities are based on the web services principles.
That’s where our knowledge of a RESTful API from the previous article will come in handy. In this article, I will show you an example of a decoupled site. For the front-end part of an application we will be using React and for the back-end, we will be using Drupal (as usual). You will see how different parts of the application can communicate with each other and in the end, you will have an understanding of how to build your own decoupled Drupal site and how to extend it in several ways.
Usually, when someone opens the Drupal site in a browser he (or she) sees the themed output (head) that Drupal generates by itself. Thus with the decoupled approach, we handle Drupal’s job of creating and displaying HTML to the front-end framework like Angular or Backbone.js. Drupal still deals with the back-end part and it is used as a content management system but now it’s “headless”. So we can link front-end framework or mobile app to Drupal and use it for displaying data. For that, we have to create a Drupal RESTful API which helps us to exchange data between the different parts of the application and connect them all together.
I already mentioned in the previous article that one of the most popular formats for an API is JSON which is provided by Drupal and almost all programming language. If a program can access the web it can use a JSON API too. So we will be using it.
This article is less theoretical and more practical. Also, I assume you are already familiar with Drupal and know how to add new content type and fields for it. If not, please begin with some tutorial over the Internet first.
First of all, let’s create a React App. It’s where the decoupled Drupal website originates. We will create a simple welcome page.
This is a simple basic folder structure with nothing extra:
React app: a basic folders structure
I will use a cdn to add React to my index.html file:
Now let’s add a <div> in index.html:
Create a file app.js inside js folder and add “React is awesome!” example:
Also include babel to transform JSX syntax (from the previous step) into ECMAScript and include app.js file inside index.html:
Now, if you try to open the index.html file in your Chrome browser (in Firefox it seems to work without advantage) you should have the “XMLHttpRequest” error. That means you need to use an HTTP server to make it work. The simplest way to start a new server is to use PHP’s 5.4 and later built-in web server. You need to evaluate this command inside of our React app directory:
php -S localhost:8000
Now if you go to http://localhost:8000/ page you should see “React is awesome!”. It means that React works and we’re ready to go.
First of all, let’s create a new Drupal installation. For your convenience, it’s recommended to choose a standard Drupal installation over the minimal because of advanced features which make navigation and site administration more comfortable. You can always find the latest release here. The version of Drupal in my example is 8.2.6.
Now it’s time to add a new content type called “Blog”. Let’s create basic blog-like fieldset:
Since title and body fields are available by default in the new content type, you only need to add an “Image” field.
Create a few nodes of “Blogs” content type.
The “Blogs” content type
Click on the extended menu in the top navigation menu and enable all modules under the web services.
Enabling Drupal modules
Now it’s time to create a required Web Service by adding a new view. I called it ‘Blogs API’. Click the ‘Provide a REST export’ checkbox and enter REST export path. In my case, it’s api/blogs.
After saving it, I also added a filter for this view by content type ‘Blogs’. It’s made for getting only blogs in API and not other content types like an article or a basic page.
The “Blogs” content type
Now, if you go to api/blogs page you should see JSON data.
I chose the axios client for the server request instead of jQuery because I need only AJAX features and I don’t want to load the whole library (jQuery). So add this into index.html:
Here is the full content of my app.js file. We will display all the blogs nodes:
Now go to http://localhost:8000/ and you should see something like this:
Headless Drupal blog
When I tested it for the first time I got this error in my browser: “No ‘Access-Control-Allow-Origin’ header is present on the requested resource”. A problem was in the cross-domain request (more information about it is here). So installation of the Chrome extension solved the problem.
Decoupled Drupal isn’t a magic elixir which will make your site super fast in a minute. In order to get a satisfying result, I’d recommend you to pay attention to a UI localization, search engines indexing problems (cannot properly index a website with client-side JS), less layout control by site builders, overhead and overlooked content. If you want to try something different and taste the future of Drupal it’s your turn to face new challenges and try to solve them with this approach.
Originally posted at the ADCI Solutions website.
The author is Mikhail Zolenko, Web Developer at ADCI Solutions
Mikhail is always looking for a new challenge that will make his mind search for a simple and beautiful solution. He does all things with love and passion, whatever it is: coding, collecting, playing the guitar or listening to the good old music.