I found examples adding a class to top level itens, so we can display an arrow in menu itens with subitens, but is seems terrible to cope with the already builtin WordPress classes, can't display the arrow with current and css hover, it just ruins all states.

Is there someway to add a <span class="arrow"></span> within the parent li instead?!

Thanks a lot!

2 Answers 2


You can use the walker_nav_menu_start_el filter:

add_filter( 'walker_nav_menu_start_el', 'wpse_add_arrow',10,4);
function wpse_add_arrow( $item_output, $item, $depth, $args ){
    //Only add class to 'top level' items on the 'primary' menu.
    if('primary' == $args->theme_location && $depth ==0){
        $item_output .='<span class="arrow"></span>';
    return $item_output;

This assumes that you're using wp_nav_menu( array( 'theme_location' => 'primary') ); to display the menu.

Updated answer in response to comments. To add the span classes to only top-level elements which have children you need to use a custom walker:

class SH_Arrow_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_lvl(&$output, $depth, $args) {
        $indent = str_repeat("\t", $depth);
        if('primary' == $args->theme_location && $depth ==0){
            $output .='<span class="arrow"></span>';
        $output .= "\n$indent<ul class=\"sub-menu\">\n";

To use this you'll need to set the walker argument in wp_nav_menu:

wp_nav_menu( array( 
     'theme_location' => 'primary', 
     'walker'=> new SH_Arrow_Walker_Nav_Menu()
 ) );
  • Oh! I found that the span show ups in all toplevel itens, I need it to show only the ones with nested items :(
    – Diana
    Commented Jun 19, 2012 at 15:52
  • See updated answer :) Commented Jun 20, 2012 at 10:34
  • Is there someway to insert things inside the menu item? Your code puts the content right after the link: <li id="menu-item-3344" class="etc"><a href="http://localhost/wp3/forums/">Fóruns</a><span class="arrow"></span> Is there someway to goes like this: <li id="menu-item-3344" class="etc"><a href="http://localhost/wp3/forums/">Fóruns New!</a>
    – Diana
    Commented Jun 20, 2012 at 18:08
  • You can edit the link text on the Appearance > Menu page. Commented Jun 20, 2012 at 18:32
  • I see, I was doing this way before you solved the issue lol I think WP adds too much classes into menu, they is hard to map all states and content :(. Thanks for help!
    – Diana
    Commented Jun 20, 2012 at 18:44

To expand on the prev answer here is how to detect if an item is a parent menu item without using the Walker class

add_filter( 'walker_nav_menu_start_el', 'cfw_add_arrow',10,4);
function cfw_add_arrow( $output, $item, $depth, $args ){

//Only add class to 'top level' items on the 'primary' menu.
if('primary' == $args->theme_location && $depth === 0 ){
    if (in_array("menu-item-has-children", $item->classes)) {
        $output .='<span class="arrow">arrow</span>';
    return $output;

Please correct me if this PHP in_array check might fail in some situations, so far I have not had any issues with it.

  • your answer is much valuable than upvote.
    – Kvvaradha
    Commented Oct 6, 2016 at 9:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.