How to set a menu link attribute programmatically

Menu Link Attributes is a great Drupal 8 module that allows you to add attributes to your menu links. For example, you can use it to add a class or target attributes to your menu links. Let's see how you can set these attributes programmatically.

First, let's add a menu link programmatically to the main menu:

use Drupal\menu_link_content\Entity\MenuLinkContent;

$menu_link = MenuLinkContent::create([
  'title' => 'New menu item',
  'link' => ['uri' => 'entity:node/1'],
  'menu_name' => 'main',
]);
$menu_link->save();

Now that we have a menu link, let's add a class to the menu item:

$menu_link->link->first()->options = [
  'attributes' => [
    'class' => 'some-class',
  ],
];
$menu_link->save();

In the same way, you can set the target attribute for the menu item:

$menu_link->link->first()->options = [
  'attributes' => [
    'target' => '_self',
  ],
];
$menu_link->save();

As you can see, the module is using the existing options property to store the attributes. The link__options column of a link field type is a blob, which stores a serialized array of options for the link. You can find more about Link field properties here.

This is how all this looks in the database:

Menu link attribute database - Drupal 8
Menu link attribute database - Drupal 8

And this is how it looks on the frontend side:

Menu link attribute frontend - Drupal 8
Menu link attribute frontend - Drupal 8

I'm a backend developer so I like talking about changing things programmatically, but you can also set attributes via user interface. Just edit your menu item and you'll see the ATTRIBUTES fieldset:

Menu link attribute UI - Drupal 8
Menu link attribute UI - Drupal 8