Skip to main content

Concepts

Decoupling Drupal is a way to leverage the power of Drupal as a content management system while using a different technology to render the content, removing the need to host the front end on the same server as the backend. Allowing the front end to be developed independently of the backend, adding more flexibility in the development process.

Any front end technology can be used to render the content, which can be exposed with a plethora of options, such as GraphQL or JSON:API. This allows for the front end to consume the content in a way that is most comfortable for the front end developer.

Drupal is a powerful content management system that can be used to create complex content models. This allows for the front end to consume the content in a structured way, focusing only in the components that represent each part of the content structure.

Overview

This is a diagram that represents the high overview of the Drupal Decoupled concept exposing data via an API interface. From the user request to the front end rendering the page.

danger

Authentication against Drupal must happen in the server side of your front end. Don't expose your client credentials to the public.

Access control via Consumers

A Consumer is used to represent a client that "consumes" an API interface which inherits a set of permissions and access control rules via scopes. Used in tandem with the Simple OAuth module to secure the communication between the front end and the backend by generating client credentials and access tokens. You can create different consumers with different scopes to fit your needs.

tip

A further explanation on the Consumer concept can be found in the Preview Published and Unpublished Content in a Decoupled Drupal Implementation article.

Preview Consumer

You can create a consumer with the Preview scope, which allows it to see all published and unpublished content. This is useful when you want to see how the content will look like before publishing it, rendering on a preview environment.

Viewer Consumer

Additionally to the preview scope, there's also a viewer scope. In this case the viewer scope only is allowed to read published content. You want to use a consumer with this scope for your production environment.

Secure communication with OAuth

OAuth is a way to secure communication between two parties using a standard protocol. It allows for secure communication between the front end and the backend by using access tokens with limited scopes.

Client ID

The client ID is used to identify and authenticate a consumer, allowing it to request access tokens. The client ID is generated when creating a consumer in Drupal.

Client Secret

The client secret is used to authenticate a consumer, allowing it to request access tokens. The client secret is generated when creating a consumer in Drupal.

Scopes

Scopes are a way to limit the access of a consumer.

Access tokens

Tokens are a way to authenticate a consumer, allowing them to access specific content. They are generated on demand, by using a consumer's client ID and secret.

All request to your Drupal instance should be authenticated using a token. This token has a limited lifetime and renewal is handled by the front end server.

Communication

Communication between the front end and Drupal is done using OAuth tokens via the use of Authorization Headers.

  1. Client requests a token using the consumer's client ID and secret to the Drupal instance.
  2. Drupal instance validates the client ID and secret and returns a token with a limited lifetime.
  3. The client uses the token to request content from the Drupal instance.
  4. Drupal instance validates the token and returns the requested content.

Site building

Structured content that can be exposed using an API interface. This is done by creating content types, fields, and others and then using the available API Interface plugins to expose the content.

In the sections below are some examples of content types and fields that are commonly used.

Title

The title is a field that can be used to store a title for a piece of content.

Body

This is a simple field that can be used to store any kind of text.

Paragraphs

Paragraphs are a way to create structured content. This can be used to create complex layouts, such as a page with multiple sections in it.

Paragraph Types can be anything you want from a simple text block or image to a complex and configurable slideshow.

Source: Paragraphs module

Articles

Usually used as a blog post, an article is a content type that has a title, a body, and other fields. This content type can be used to create blog posts or other types of articles, usually under a /blog route.

Basic Pages

A basic page is a content type commonly used that has a title, a body, and other fields. Any route that's not a blog post or an article can be considered a basic page, like the home page, about page, contact page, etc.

Meta tags

Meta tags are a way to add metadata to a page. This can be used to add information about the page, such as the title, description, and keywords, used to improve SEO.

Redirects

Redirects are a way to redirect a page to another page. This can be used to redirect old URLs to new URLs. Drupal generates redirects when a node slug is changed or by demand.

Visual Editor

Drag and drop editor that allows for creating stacked layouts backed by paragraphs. Handy for creating and reorganizing the content of a page without the need to write code.

Make your content available to the front end

Content can be exposed using different methods, such as GraphQL, JSON:API. After deciding how your content will be structured, you can expose the fields you want to consume in the front end.

GraphQL

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. It allows you to query only the fields you need, making it easier to consume content.

Use the recommended GraphQL and GraphQL Compose modules in order to select the fields you want to expose to the front end.

JSON:API

JSON:API is a specification for building APIs in JSON. It provides a way to interact with your API in a simple way, using a standard format.

Use the core JSON:API module to expose content using the JSON:API specification.

Decoupled front end

A decoupled front end is an application that renders HTML code, that's not necessarily hosted on the same server as the backend and can be developed independently of the backend.

Focusing only on the front end, you can use any technology you want, such as Remix, Next or others.

Consuming content from Drupal

One of the options to consume content from Drupal is by using GraphQL queries and fragments. This enables you to focus on developing components that match the shape of the data you want to consume, develop once, use everywhere.

note

Drupal Decoupled is not limited to GraphQL, you can also use JSON:API as the API Interface.

In order to consume content from your Drupal instance you need:

  1. The proper Drupal API endpoint.
  2. A consumer already configured in your Drupal instance.
  3. A valid token derivated from the consumer's client ID and secret, used to authenticate further requests.
  4. An authorized content request, such as a GraphQL query or JSON:API request.
  5. A way to handle the response and render the content.

Creating components

Components are the building blocks of your front end. They are reusable pieces of code that can be used to create complex layouts. In Drupal Decoupled, components are data driven, meaning that they will be rendered based on the data types fetched from the API.

Catch all route /*

This is front end piece that glues the implemenatation together. On a decoupled scenario you won't be creating a route per route defined in your CMS, instead you will create a single route that will handle all requests /*.

The front end will pass the requested route to your Drupal API, using the response returned by the API interface to render a page by matching a payload's types to one or more components.

tip

Each front end framework has a way to create a catch all route. Check the chosen front end framework's documentation for additional information.

Redirects

Usually if you create a redirect in your Drupal instance, you will need to handle that redirect payload in your front end too. This depends on the framework you're using, but generally you can achieve this by following these steps:

  1. Fetch the route to your Drupal instance
  2. Check the response payload, look for a redirect
  3. If a redirect is found, redirect the user to the new location with a 301 or 302 status code depending on the redirect type returned by the API.