Skip to content

Early-bird lifetime licence: $199 once, for the first 200 buyers only. See the offer

wp_nav_menu_items

Filters the list items of a classic menu printed by wp_nav_menu(). Use it to add a link, such as Log in or Log out.

  • Type Filter
  • From WordPress
  • Since 3.0.0
  • Fired in wp-includes/nav-menu-template.php

When it fires

WordPress applies wp_nav_menu_items inside wp_nav_menu(), after it has built the items for a menu and before it wraps them in the . You get the items as one HTML string, plus the arguments the theme passed.

It only works with classic menus. Block themes use the Navigation block, which doesn't call wp_nav_menu().

Parameters

Parameters
$itemsstring The HTML list content for the menu items.
$argsstdClass An object containing wp_nav_menu() arguments.

What to return

The menu items as an HTML string.

Example: Add a Log in / Log out link to the main menu

PHP
add_filter( 'wp_nav_menu_items', function ( $items, $args ) {
	if ( 'primary' !== $args->theme_location ) {
		return $items;
	}
	if ( is_user_logged_in() ) {
		$url   = wp_logout_url( home_url( '/' ) );
		$label = __( 'Log out', 'my-snippets' );
	} else {
		$url   = wp_login_url();
		$label = __( 'Log in', 'my-snippets' );
	}
	$items .= sprintf(
		'<li class="menu-item menu-item-login"><a href="%1$s">%2$s</a></li>',
		esc_url( $url ),
		esc_html( $label )
	);
	return $items;
}, 10, 2 );

Good to know

  • Check $args->theme_location so you only change the menu you mean. Location names vary by theme; look for register_nav_menus() in the theme's code.
  • To target one menu by its slug, use the wp_nav_menu_{$menu->slug}_items filter.
  • If no menu is assigned to the location, the theme's fallback is shown and this filter doesn't run.

Move your snippets over this afternoon.

Importing changes nothing until you switch over, and your old shortcodes keep working.