How I decoupled Drupal 8 with React.js behind Nginx.

Drupal is a great content management platform. It has an awesome community behind it and is used by many companies. The recent rise of many frontend libraries like React, Angular and Vue has given us an option to be more flexible on the frontend. In the past the frontend was coupled with monolithic architectures, but nowadays when organizations need to be agile there are more options to be flexible.

When my boss told me that we needed a CMS for a static website we were running, I instantly thought of Drupal 8 and migrating the garden variety HTML to React. So here is how I did it.

Firstly, I had to prepare the server. We are running AWS linux but any linux flavor will do. I will assume that you already have installed React and Drupal on your server. The only thing I need you to do is move them under the same directory:

/var/www/html

React is in subfolder client and Drupal – server.

Now, let’s install nginx:

sudo yum install nginx

Nginx will differentiate between the two applications based on server name. So what I did is I run React on domain.com and Drupal on portal.domain.com. In addition to port 80 I also run Drupal on the server’s localhost:8080 which is closed to the outside world. This will help us proxy /api/requests and /sites/default/files from Drupal to React without entering the full url.

First I added the configuration for React in /etc/nginx/nginx.conf:

server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  domain.com;
        root         /var/www/html/client/build;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
          try_files $uri /index.html;
        }

        location /sites/default/files/ {
            proxy_pass http://127.0.0.1:8080/sites/default/files/;
        }

        location /api/ {
            proxy_pass http://127.0.0.1:8080/api/;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

On line 5 Nginx will look in the directory for index.html. Look at proxy_pass directive. Nginx will proxy data from these uri-s to localhost:8080

Nginx has a pretty good explanation on how to configure Drupal. I put the config file in /etc/nginx/conf.d/drupal.org.conf. I only changed the beginning, here it is:

listen 80;
listen 8080;
server_name portal.domain.com;
root /var/www/html/server;

I am listening on both 80 and 8080. 80 is open to my load balancer and 8080 is closed for the outside world.

If everything is configured properly you should be able to go to the server’s ip (load balancer DNS) and hitting domain.com and portal.domain.com will show you React and Drupal respectively.

Before you create some endpoint you have to configure your backend Cros-Site HTTP requests since you want your naked domain to fetch data from your subdomain portal.domain.com. In your Drupal subfolder go to sites/default/services.yml and edit the cors.config setting:

 cors.config:
    enabled: true
    # Specify allowed headers, like 'x-allowed-header'.
    allowedHeaders: ['Access-Control-Allow-Origin', 'x-csrf-token', 'authorization', 'content-type', 'accept', 'origin', 'x-requested-with']
    # Specify allowed request methods, specify ['*'] to allow all possible ones.
    allowedMethods: ['POST', 'GET', 'OPTIONS', 'DELETE', 'PUT']
    # Configure requests allowed from specific origins.
    allowedOrigins: ['*.domain.com', 'http://www.domain.com']
    # Sets the Access-Control-Expose-Headers header.
    exposedHeaders: false
    # Sets the Access-Control-Max-Age header.
    maxAge: false
    # Sets the Access-Control-Allow-Credentials header.
    supportsCredentials: true

Now create some content in Drupal, install the API module and enable it for that content type. Give the content types you created some aliases (/api/my-content-type-alias). Remember that everything with api prepended will be proxied. You can install axios on the frontend and request the relative url. You should be able to get the data back.

Now try uploading an image and request it with a relative url: /sites/default/files/my-image.png. You should be able to see that too.

chevron_left
chevron_right

Leave a comment

Your email address will not be published. Required fields are marked *

Comment
Name
Email
Website