Declaration of mandoe_menu_walker::start_el(&$output, $item, $depth, $args) must be compatible with Walker::start_el(…)

An entirely different approach.

nav menu item are stored in posts table, so you can technically attach a post_meta into it, even other data like nav item class already stored in post mata table. However this wasn’t easy to do before.

but after 5.4.0 release, they have implemented hooks to easily do this.

Here’s the full step

Add Custom Meta box on Nav item

add_action( 'wp_nav_menu_item_custom_fields', function( $id, $navItem) {

  wp_nonce_field( 'nav_menu_icon_nonce', '_nav_menu_icon_nonce_name' );
  $nav_menu_icon = get_post_meta( $id, '_nav_menu_icon', true );
  ?>
  <p class="field-nav-icon nav-icon description-wide">
    <label for="edit-menu-item-nav-icon-<?php echo $id ;?>">
      Nav Icon<br>
      <textarea id="edit-menu-item-nav-icon-<?php echo $id ;?>" class="widefat edit-menu-item-nav-icon" rows="3" cols="20" name="menu_item_nav_icon[<?php echo $id ;?>]"><?php echo esc_attr( $nav_menu_icon ); ?></textarea>
      <span class="description">Add icon on menu.</span>
    </label>
  </p>
  <?php
}, 10, 2 );

There should be another box in nav item after adding the code above like this
enter image description here

Then save the value of that field into post meta

add_action( 'wp_update_nav_menu_item', function($menuId, $menuItemId) {

  // current_user_can( 'unfiltered_html' ) is a wordpress role which ensure the user can post unfiltered html
  if ( ! isset( $_POST['_nav_menu_icon_nonce_name'] ) || ! wp_verify_nonce( $_POST['_nav_menu_icon_nonce_name'], 'nav_menu_icon_nonce' ) || !current_user_can( 'unfiltered_html' ) ) 
    return $menuId;
    
  if ( isset( $_POST['menu_item_nav_icon'][$menuItemId]  ) ) {
    update_post_meta( $menuItemId, '_nav_menu_icon', $_POST['menu_item_nav_icon'][$menuItemId] );
  } else {
    delete_post_meta( $menuItemId, '_nav_menu_icon' );
  }
}, 10, 2 );

and thats it, you now have additional data connected to each menu item for nav icon that supports text and html, you can add html tag like <img /> for adding image as menu icon, or svg,

To display on the front-end, this depends on your set-up and where you want them to show

an example below that modify the nav menu item title via nav_menu_item_title filter and include the icon using get_post_meta to pull the icon value

add_filter( 'nav_menu_item_title', function( $title, $item) {
  
  if( is_object( $item ) && isset( $item->ID ) ) {
    
    $navIcon = get_post_meta( $item->ID, '_nav_menu_icon', true );
    
    if ( ! empty( $navIcon ) ) {
      $title="<span class="icon">".$navIcon.'</span>' . $title;
    }
    
  }
  return $title;
  
}, 10, 2 );

and the title would show the svg icon if there is

enter image description here

tech