Missing support for <button> token in Links props when mapping menus via UI Patterns

Created on 15 May 2025, 3 days ago

Hi,

Problem/Motivation

When mapping a menu (e.g. main or footer) to a Links-type prop in a UI Patterns pattern, Drupal allows the use of special tokens in the menu link URLs:

  • <front> : works as expected
  • <nolink> : works as expected
  • <button>: the link is completely removed from the output

This behavior is problematic, as Drupal's admin UI explicitly allows adding button-type links to menus. However, the UI Patterns module does not currently support this case properly, which prevents the button from being rendered.

Steps to reproduce

  • Drupal core version: 10.4
  • UI Patterns module version: 2.x
  • Menu items are MenuLinkContent entities.

Links are mapped to a prop of type Links, using a schema defined by LinksPropType, which expects the following structure:

[
  'type' => 'object',
  'properties' => [
    'title' => ['type' => 'string'],
    'url' => ['$ref' => 'ui-patterns://url'],
    'attributes' => ['$ref' => 'ui-patterns://attributes'],
    'link_attributes' => ['$ref' => 'ui-patterns://attributes'],
    'below' => [
      'type' => 'array',
      'items' => [
        'type' => 'object',
      ],
    ],
  ],
]

However, when a link uses the <button> token in the Link field, the preprocessing handled by the normalize() method in UrlPropType returns an empty string ('') for the URL.

As a result, the schema validation for LinksPropType either rejects or silently ignores the item, because it no longer matches the expected format for a valid link.

This use case can be essential, particularly for accessibility reasons, such as:

  • A parent menu link used only to trigger expand/collapse behavior
  • A menu item that opens a consent modal
  • A purely interactive navigation element that doesn’t need an actual URL

Proposed resolution

Menu items with a <button> URL should be included in the Links prop, with an identifiable format for example, a type: 'button' field or a boolean is_button allowing the front-end integrator to distinguish and render the element appropriately (e.g., using a <button> instead of an <a> tag).

Marc

🐛 Bug report
Status

Active

Version

2.0

Component

User interface

Created by

🇷🇪Réunion Martygraphie Saint-Denis (Réunion)

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024