Decoupled menus overview
This documentation needs review. See "Help improve this page" in the sidebar.
Decoupled Menus provides the best way for JavaScript front ends to consume configurable menus managed in Drupal. This makes it easy for a front-end developer to consume that menu data in order to render a navigation instead of hardcoding it. This also means that non-developers can manage application menus without writing code!
This functionality is built into Drupal core, so you get all the other benefits that you would expect from the best CMS on the planet. This includes security, caching, and translations as well. You can actually serve multilingual menu data out to any number of decoupled applications with ease.
While this functionality can be used in many ways, there is one primary use case that Decoupled Menus is currently serving: menus that are global and static. This is a menu that will remain the same from page to page or screen to screen, and is intended to provide universal navigation options for decoupled applications. These menus are the same for all users.
In the future, decoupled menus functionality could be expanded to cover menus that are contextually aware. This would be a menu that may change based on the context of the page or the specific user. As an example, there may be specific menu items that are available based on the user and their role or access in the application. Additional discussion related to this concept can be found by consulting the following issue.
In addition to the back end functionality provided by the module, there are also tools available to make it easier to use the API data in the front end including libraries and web components.
Backend
Quickest way to have a working setup: drush, sqlite + built-in php server.
Setting up the Drupal backend
Use drush and a sqlite DB to setup the website.
composer create-project drupal/recommended-project:^10.1.x-dev decoupled
cd decoupled
composer require drush/drush
./vendor/bin/drush si demo_umami --db-url=sqlite://.ht.sqliteEnable the linkset endpoint
It is possible to enable the linkset endpoint in site settings under Webservices on the configuration page. The url for this setting is /admin/config/services/linkset.
Finding the setting on the configuration page

Enable the linkset endpoint

This enabled an new endpoint at system/menu/[menu system name]/linkset. This endpoint serves menu's as a linkset.
Serving Drupal
Use the built-in PHP server (use another terminal)
cd web
php -S localhost:8888 .ht.router.phpGetting Menu data
Menu data is available at /system/menu/[menu name]/linkset, where "[menu name]" is the machine name of the menu. For instance, to retrieve the main menu:
curl http://localhost:8888/system/menu/main/linksetIf your frontend is on a different domain than your backend, you can enable CORS headers to allow javascript requests to work from the frontend.
To access the menu data in a different language add the language prefix or language domain to the request. To get the menu in Spanish, add the es prefix to the URL.
curl http://localhost:8888/es/system/menu/main/linksetThe endpoint respects user permissions, so you can only access the admin menu data when logged in with an appropriate user account.
curl http://localhost:8888/system/menu/admin/linksetSample response format
The format of the response follows the linkset IETF draft to allow some predictability on the structure of the response.
The menu data is returned in a flat array, the information in the drupal-menu-hierarchy makes it possible to render the structured menu.
{
"linkset": [
{
"anchor": "\/system\/menu\/admin\/linkset",
"item": [
{
"href": "\/en\/admin",
"title": "Administration",
"drupal-menu-hierarchy": [
".000"
],
"drupal-menu-machine-name": [
"admin"
]
},
{
"href": "\/en\/admin\/structure",
"title": "Structure",
"drupal-menu-hierarchy": [
".000.001"
],
"drupal-menu-machine-name": [
"admin"
]
},
{
"href": "\/en\/admin\/structure\/block",
"title": "Block layout",
"drupal-menu-hierarchy": [
".000.001.000"
],
"drupal-menu-machine-name": [
"admin"
]
},
{
"href": "\/en\/admin\/structure\/contact",
"title": "Contact forms",
"drupal-menu-hierarchy": [
".000.001.001"
],
"drupal-menu-machine-name": [
"admin"
]
},
{
"href": "\/en\/admin\/structure\/display-modes",
"title": "Display modes",
"drupal-menu-hierarchy": [
".000.001.003"
],
"drupal-menu-machine-name": [
"admin"
]
},
{
"href": "\/en\/admin\/structure\/display-modes\/form",
"title": "Form modes",
"drupal-menu-hierarchy": [
".000.001.003.000"
],
"drupal-menu-machine-name": [
"admin"
]
},
{
"href": "\/en\/admin\/structure\/display-modes\/view",
"title": "View modes",
"drupal-menu-hierarchy": [
".000.001.003.001"
],
"drupal-menu-machine-name": [
"admin"
]
}
]
}
]
}Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion