Add Menu Items at the start or end or in a certain place with wp_nav_menu_filter

wp_nav_menu_filter allows you add items at the end of a menu in WordPress but what about adding an item at the start of a menu or in a specific place.

add_filter( 'wp_nav_menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to end of menu
 */
function prefix_add_menu_item ( $items, $args ) {
   if( $args->theme_location == 'primary' )
       $items .=  '<li class="menu-item">...</li>';
      } 
       return $items;
}

So here a custom menu item is added to the menu in the primary location, if you don’t have menu locations you can target the menu directly by altering the filter name to include the menu ID – let’s say the menu ID is menu-primary-menu you would just use primary-menu like so…

add_filter( 'wp_nav_menu_primary-menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to end of menu
 */
function prefix_add_menu_item ( $items, $args ) {
       $items .=  '<li class="menu-item">...</li>';

       return $items;
}

Get your underscores and dashes right.

Add menu items at the start of a menu with wp_nav_menu_items

Change the position of the $items parameter and return a new parameter $new_items that includes the new menu item $start_menu_item followed by the existing menu items $items

add_filter( 'wp_nav_menu_primary-menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to end of menu
 */
function prefix_add_menu_item ( $items, $args ) {
       $start_menu_item =  '<li class="menu-item">...</li>';
       $new_items = $start_menu_item . $items;

       return $new_items;
}

Adding a custom item to a specific place in the menu

Works only on single level menu, so will fail with submenus.

add_filter( 'wp_nav_menu_primary-menu_items', 'prefix_add_menu_item', 10, 2 );
/**
 * Add Menu Item to a specific place in the menu
 */
function prefix_add_menu_item ( $items, $args ) {
        
$items_array = array();
        while ( false !== ( $item_pos = strpos ( $items, '<li', 10 ) ) ) // Add the position where the menu item is placed
        {
            $items_array[] = substr($items, 0, $item_pos);
            $items = substr($items, $item_pos);
        }
        $items_array[] = $items;
        array_splice($items_array, 9, 0, '<li class="menu-item">...</li>'); // insert custom item after 9th item one

        $items = implode('', $items_array);
       
       return $items;
}

So in the code above the custom item is inserted as the 10th item, there are 2 instances in the code where the position needs to be inserted as commented in the code.

The menu is effectively split into 2 and the custom item is appended after the first then the second part of the menu is appended after that.

Ref & Ref

4 Comments

  1. Pradeep Maheepala on April 11, 2024 at 7:27 am

    You sir, are a legend! Thank you so much for the snippet.

  2. Greg on August 12, 2021 at 1:52 pm

    While trying to add a menu item at the beginning of a menu, the code doesn’t work. I have the following menus registered in the theme. I’m trying to add the new menu item to the menu called menu-4. I updated the filter to be wp_nav_menu_menu-4_items however it doesn’t return the new item in the menu.

    register_nav_menus( array(
    ‘menu-1’ => esc_html__( ‘Primary’, ‘honeycomb’ ),
    ‘menu-2’ => esc_html__( ‘Mobile Cat Products’, ‘honeycomb’ ),
    ‘menu-3’ => esc_html__( ‘Top Bar’, ‘honeycomb’ ),
    ‘menu-4’ => esc_html__( ‘Shopify Nav’, ‘honeycomb’ ),
    ) );

    add_filter( ‘wp_nav_menu_menu-4_items’, ‘prefix_add_menu_item’, 10, 2 );
    /**
    * Add Menu Item to beginning of menu
    */
    function prefix_add_menu_item ( $items, $args ) {
    $start_menu_item = ‘…’;
    $new_items = $start_menu_item . $items;

    return $new_items;
    }

  3. Patrick Mackaaij on October 18, 2020 at 5:57 pm

    Shouldn’t all add_filters point to ‘wp_nav_menu_items’?

    • Neil Gowran on October 18, 2020 at 9:48 pm

      You can amend the filter to target specific menus.

Leave all Comment