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