Skip to main content
Drupal is a registered trademark of Dries Buytaert
Release: Views Bootstrap 5.5.4 — Minor update available for module views_bootstrap (5.5.4). Release: Rightup theme 1.0.3 — Minor update available for theme vartheme_bs5_rightup (1.0.3). Release: CommentOn 1.0.6 — Minor update available for module commenton (1.0.6). Release: ChatGPT Ads 1.0.3 — Minor update available for module chatgpt_ads (1.0.3). Release: Opensolr Search 5.1.3 — Minor update available for module opensolr_search (5.1.3). Release: ServiceM8 Webform Integration 1.2.1 — Minor update available for module servicem8_webform (1.2.1). Release: PostfixAdmin 1.0.0 — Initial release available for module postfix_admin (1.0.0)! Release: ip_analyser 1.0.3 — Minor update available for module ip_analyser (1.0.3). Module Revived: Swagger-PHP OpenAPI 3 documentation generator 1.0.0 — Module swagger_php updated after 10 months of inactivity (1.0.0). Security Coverage: Microsoft Azure AI — Module ai_provider_azure now has official Drupal security advisory coverage.

The Decoupled Pages module provides a quick and simple way to define new Drupal routes which can be overtaken by a single page application, often written in Javascript using React, Vue.js, or Ember (to name a few common frameworks).

How to create a decoupled page

1. Defining a route

To define a new decoupled page, you define a new route in your module's routing file. The basic structure of your route definition remains unchanged. You can add route requirements, route defaults and route options pretty much as normal. The only caveat is that you must not define a _controller or _form route requirement.

Instead, you'll define a _decoupled_page_main route requirement. The value of this key is the name of an asset library containing your single page application and its dependencies. It should take the form your_module/name. You can define this asset library in a your_module.libraries.yml file, but any module can provide an asset library.

Here is an example of a decoupled page route definition:

your_module_name.foo:
  path: /some/path/of/your-choosing
  defaults:
    _decoupled_page_main: decoupled_pages/route_test
  requirements:
    _access: 'TRUE'

Once your route definition has been created, a new route will be available after you've rebuilt Drupal's cache (make sure to enable your module too 😉).

The decoupled_pages/route_test asset library is pre-defined by this module. You can use it to test your route without first registering your own library. If your route works, you should be able to visit the path you defined. Check the browser console for a message saying that your route worked.

Warning: _access: 'TRUE' will make your route accessible to everyone.

2. Adding your single page application

This module will place an empty <div> into the main content region of your active theme. It will have the HTML ID decoupled-page-root, like so:

<div id="decoupled-page-root"></div>

Your JavaScript can attach to that element.

Once you've defined an asset library of your own. Go ahead and point your route's _decoupled_page_main to that library.

3. Customize for your needs

Paths routed in JavaScript

If your single page application defines its own routes, you'll want to make sure that your users can link directly to them. In order to do that, Drupal needs to know about those paths. You can add additional paths for Drupal to serve your application code by setting the _decoupled_page_paths route option, like so:

  options:
    _decoupled_page_paths:
      foo: /some/path/of/your-choosing/foo
      bar: /some/path/of/your-choosing/bar
      foobaz: /some/path/of/your-choosing/foo/baz

Adding additional CSS and JavaScript libraries

You may also need the ability to attach additional JavaScript or CSS to your decoupled pages that can't be included in your main asset library. You can tell Drupal about those assets by defining the _decoupled_page_assets route option, like so:

  options:
    _decoupled_page_assets:
      - your_module/some_extra_css

Passing configuration to your JavaScript application

In order to keep your JavaScript application from hardcoding certain assumptions (e.g. API URLs), you may want to pass configuration to your JavaScript via the root data element. Custom data attributes are an excellent way to pass information from the backend to your JavaScript application. To do that, you can specify a _decoupled_page_data route default, like so:

  defaults:
    _decoupled_page_data:
      api-base-path: /my/api/v1

Your data attribute names must be strings containing only the lower-case letters a-z and dashes and must not begin or end with a dash. You data attribute values must also be strings. You can access these data attributes from JavaScript, like so:

const root = document.getElementById('decoupled-page-root');
root.dataset.apiBasePath === '/my/api/v1'; // true

Notice that the dasherized key name that you defined in YAML is lower-camel-cased in JavaScript. This is a browser behavior, not a feature of this module.

Defining data attributes dynamically

If you need to be able to define data attributes described above dynamically, you may do so. There are three steps. First, create a class which implements Drupal\decoupled_pages\DataProviderInterface (see the decoupled_pages_test module for an example implementation). Second, define a service in your_module.services.php tagged with decoupled_pages_data_provider:

services:
  your_module.your_custom_data_provider:
    class: Drupal\your_module\YourCustomDataProvider
    tags:
      - { name: decoupled_pages_data_provider }

Finally, register your data provider on your decoupled route definition by its service ID:

  defaults:
    _decoupled_page_data_provider: your_module.your_custom_data_provider

The rules for data attribute names and values described above still apply.

Depends on

Dependencies of the latest stable release

No dependencies recorded for this project.

Required by

Tracked projects that depend on this one

No tracked projects depend on this one yet.

Activity

Tracked releases
1
Tracked since
Jan 2024
Latest release
2 years ago
Releases (12 mo)
0
Maintenance
Dormant

Releases

Version Type Core Release date
8.x-1.1 Stable Jan 4, 2024