A WordPress website wouldn’t be much without its menus and submenus. Customizing those menus to your liking from within WordPress is also straightforward. As such, your WordPress menu is a ‘front line’ tool to get a high search ranking and keep visitors on site.
The dedicated screens within WordPress belie how complex your menus can be. You’re also able to display menus in several locations on your site. If you have the coding skills, you can customize your WordPress menu with almost infinite possibilities.
For this post, we’re going to give you an in-depth guide to creating a WordPress menu. We’ll also show you how to take the functionality and enhance it in a few different ways.
Check Out Our Video Guide to Creating and Customizing a WordPress Menu
The Anatomy of a WordPress Menu
For the uninitiated, a WordPress menu is often a collection of links (including dropdowns). It’s a straightforward piece of functionality that is but one “vertebra” in the backbone of your website.
We’ll get into where you will see menus on a website in more detail in the next section. For now, know that they can fit anywhere you’d like to display them. You may only have a few pre-selected options (based on widget areas). In a technical sense, though, a menu can go anywhere.
Of course, a WordPress menu is paramount for navigating a website. If you have a clear and defined navigation menu, this will help users get around your site, and it’ll keep your bounce rate down.
They also serve another purpose too: your menus help with your search engine optimization (SEO). Optimizing a WordPress menu for SEO is more about what to leave out than what you put in. For starters, you can do away with elements — such as tag clouds — and keep the number of links you include low.
While Google lets you add up to 250 links on a page, keeping your “link value” high is essential. As such, cutting down the number of external links will serve you well over the long term.
The Different Types of WordPress Menu Structures
As you might already understand, depending on your application’s needs, you can opt for different WordPress menu structures.
Header menus, for example, are the most common because they deal with primary site navigation. You will often see smaller menus above the main navigation, too, as this is an excellent place for social media icons, search bars, and more.
The website of Kinsta partner SAU/CAL has a “fly-in” menu that includes navigation and social links:
This menu shows that there are more use cases for a WordPress menu than navigating a site. Using WordPress’ built-in functionality (more on this later), you can create a menu for almost anything you need.
Just as popular as header navigation is the footer. You’ll often use this area to repeat your primary navigation for users who scroll down. Also, it’s an excellent place to offer more context-based links for your products and services:
You’ll also see menus within a sidebar if the site uses it:
While you won’t see primary navigation here in many cases, it’s a traditional place for social links, blog post archives, and much more.
How to Create a Custom WordPress Menu (3 Methods)
Creating a WordPress menu is a no-nonsense process, regardless of your level of expertise. There are three main ways to get the job done: use WordPress’ built-in functionality; install a suitable plugin or get your hands dirty with code.
Next, we’ll show you how to create a WordPress menu using all three approaches.
1. Use WordPress’ Built-in Functionality to Create Your Menu
WordPress has built-in tools to help you create a menu. A dedicated screen within the WordPress admin will be familiar to all but the newest users.
Of course, using the native functionality to create your WordPress menu has numerous benefits. For starters, you have complete compatibility with your site. Also, you can build your menus using a familiar interface and native tools.
To get there, head to the Appearance > Menus page within WordPress:
This screen divides into a few different sections. At the top, you’ll find the option to select a current menu or create a new one:
If you decide to build a new menu, give it a name and check out the Menu Settings section:
There are a lot of checkboxes here, but you’ve got two main decisions to make:
- Add top-level pages to the menu automatically. “Top-level” here means pages you’d create within WordPress that aren’t children of other pages. For example, a blog post isn’t a top-level page because it will have a parent archive page in many cases (e.g. /blog). On the other hand, a contact page is often top-level because it won’t usually have a parent page.
- The menu location. Each theme will have its menu locations. Unless you alter your theme’s core files, the theme developers have hard-coded these menu locations. Some themes may allow you to customize them through their settings.
Once you’re ready, click the Create Menu button. The screen will refresh and will show that you’re in your new menu. Next, take a look at the left-hand side of the screen:
This screen lists all the posts, pages, taxonomies, and other linkable assets on your site. You build your menu by checking boxes on the left, then clicking the Add to Menu button.
That’ll move them to the central section of the Menus screen:
Here, you can drag and drop menu items into place. If you click the expansion arrow next to each item, you can also set a label for your menu item or remove it:
Once you click Save Menu, you’re good to go. If you expand the Screen Options menu at the top of the screen, though, there’s more you can do with your WordPress menu:
The Screen elements group lets you show menu meta boxes in the left-hand sidebar. In contrast, the Show advanced menu properties group displays link targets, descriptions, and CSS classes for list items.
There’s one more aspect of the Menus screen worth noting. The Custom Links box lets you set a link of your choosing, rather than a predefined page on your site:
This option is how you can add social media links to your WordPress menu. The platform will pull the correct icon for you based on the site you select, giving you the opportunity for well-displayed logos for the sites you choose.
2. Use a Plugin to Create Your Custom WordPress Menu
The immediate solution for adding functionality to WordPress is through plugins. The previous section has covered why WordPress’ native option is almost all you need, but plugins can expand on that functionality.
There’s a question of whether you’d need a dedicated (and additional) plugin to create a WordPress menu, although there are many good reasons for doing so. For starters, you will often make a menu based on a style you can’t access under the default setup. Specific responsive designs, “mega menus,” and more are all available to you through plugins.
What’s more, you can build menus using a dedicated editor and choose from preset templates in lots of cases. Coupled with extensive customization options, you have a “no-code” solution that will provide a WordPress menu that works for your site.
For example, the Max Mega Menu plugin offers no surprises in what you can achieve:
Once it’s installed and activated, you’ll find a new Mega Menu panel within WordPress:
If you look at the Menu Locations screen, you’ll notice that there are more customizations available to you:
You can also apply menu themes and edit them with a similar scope to some of the best page builders on the market:
There is a lot more we could dig into here, though we’d be repeating ourselves. We encourage you to check out our previous post on WordPress menu plugins. We go into detail on how to choose the right plugin for you and how to use it.
3. Write Code to Create Your Custom WordPress Menu
Coding your own WordPress menu is a reliable way to achieve your goal for the brave (or if you’re a developer creating a new WordPress theme). Of course, you’re not going to crack open a code editor on a day-by-day basis to add a menu. For that, you’ll use the native WordPress tools (or maybe a plugin).
That said, learning how to code a WordPress menu is a vital requirement if you want to develop themes. There are four parts to success:
- Register your menu.
- Display the WordPress menu on the front end.
- Show additional content within your menu or its items.
- Define a callback.
We’ll assume that you’re handy with a code editor, you have a development environment to work in, and your skills are sharp. If you don’t yet have a theme to work with, you could use WordPress’ default options or pick one from our list of fastest WordPress themes.
When you’re ready, you’ll want to open the theme’s functions.php file. Note that this is different from the general WordPress file of the same name. Here, you need to register your menu. In other words, you have to tell WordPress what to display on the Appearance > Menus page. To do this, you use the register_nav_menus() function:
function register_my_menus() {
register_nav_menus(
array(
'header' => __( 'Header Menu' ),
'other' => __( 'Other Menu' )
)
);
}
add_action( 'init', 'register_my_menus' );
This code tells the Manage Locations tab within WordPress to display two menus: Header Menu and Other Menu:
Next, you have to display your menu using the wp_nav_menu() function. You’ll add this into the template file that corresponds with where you’d like to display the menu. In our case, we’re going with the header, so we’ll add the following code to our theme’s header.php file:
wp_nav_menu( array( 'theme_location' => 'header' ) );
It could be that this code is wrapped in an if
statement, along with some of your other menus, so you’ll want to follow the conventions you find.
At this point, you could work with the menu in WordPress much like any other. Though, you may also want to consider adding additional content to your menu items. For example, you can expand the defined array to include HTML tags that will render on output:
wp_nav_menu(
array(
'menu' => 'primary',
'link_before' => '',
'link_after' => '',
)
);
Your final task here is to define a callback. By default, WordPress displays a populated menu when the specified one isn’t found. As an alternative, WordPress will display a menu of pages when no custom menu is selected. If this isn’t your desired action, you can set a different parameter for the theme-location
argument and also add in a fallback_cb
argument:
wp_nav_menu(
array(
'menu' => 'primary',
// do not fall back to first non-empty menu
'theme_location' => '__no_such_location',
// do not fall back to wp_page_menu()
'fallback_cb' => false
)
);
Once you understand how to create a WordPress menu, you can begin to enhance the functionality. We’ll look at this in our final section to create a custom menu meta box for WordPress.
How to Enhance Your WordPress Menu
Because this section is advanced, we’ll make some assumptions before we continue:
- You know how to create a WordPress menu using PHP.
- Your PHP skills are good enough to follow along with some advanced topics.
- You know how to register and initialize a WordPress plugin.
It’s beyond the scope of this article, but you can use the WordPress Plugin Boilerplate Generator to create a new, standardized plugin template.
When you’re ready, create and upload your plugin to WordPress:
Next, navigate to the plugin’s folder and open the main file. Here, add the following code:
/**
* Add menu meta box
*
* @param object $object The meta box object
* @link https://developer.wordpress.org/reference/functions/add_meta_box/
*/
function custom_add_menu_meta_box( $object ) {
add_meta_box( 'custom-menu-metabox', __( 'Authors' ), 'custom_menu_meta_box', 'nav-menus', 'side', 'default' );
return $object;
}
add_filter( 'nav_menu_meta_box_object', 'custom_add_menu_meta_box', 10, 1);
The WordPress add_meta_box() function will register a meta box within the WordPress admin. There are a few arguments you’ll want to reference within the official documentation. We also use the nav_menu_meta_box_object() filter because there is no action within the nav-menus.php file to hook into. This statement determines whether the function adds a menu item’s meta box for an object type. When the filter runs, add_meta_box
registers the custom meta box.
Defining a Callback Function
Next, we can define a callback function to produce the HTML content for the meta box:
/**
* Displays a metabox for an author menu item.
*
* @global int|string $nav_menu_selected_id (id, name or slug) of the currently-selected menu
*/
function custom_menu_meta_box(){
global $nav_menu_selected_id;
$walker = new Walker_Nav_Menu_Checklist();
...
}
The global variable remembers the current menu ID, while $walker
stores a new instance of the Walker_Nav_Menu_Checklist
object. That’ll build the HTML list of menu items.
From here, we have to determine the active tab in the custom meta box. To do this, we set the value of $current_tab
, working within the ellipsis set in the previous code block.
We’re using two tabs here, but you can add as many as you need:
$current_tab = 'all';
if ( isset( $_REQUEST['authorarchive-tab'] ) && 'admins' == $_REQUEST['authorarchive-tab'] ) {
$current_tab = 'admins';
} elseif ( isset( $_REQUEST['authorarchive-tab'] ) && 'all' == $_REQUEST['authorarchive-tab'] ) {
$current_tab = 'all';
}
The following line will get all users with write privileges and add many properties to the $authors
object:
$authors = get_users( array( 'orderby' => 'nicename', 'order' => 'ASC', 'who' => 'authors' ) );
$admins = array();
/* set values to required item properties */
foreach ( $authors as &$author ) {
$author->classes = array();
$author->type = 'custom';
$author->object_id = $author->nickname;
$author->title = $author->nickname . ' - ' . implode(', ', $author->roles);
$author->object = 'custom';
$author->url = get_author_posts_url( $author->ID );
$author->attr_title = $author->displayname;
if( $author->has_cap( 'edit_users' ) ){
$admins[] = $author;
}
}
$removed_args = array( 'action', 'customlink-tab', 'edit-menu-item', 'menu-item', 'page-tab', '_wpnonce' );
?>
Here, get_users
returns an array of $user
objects selected by the specified parameters. The who
parameter will force WordPress to query the database for users who have writing privileges.
Also, the $admins
array will store an array of authors, while $removed_args
will store a list of query variables to be removed.
You can now print the meta box markup. To do that, let’s build the tab labels and links.
<div id="authorarchive" class="categorydiv">
<ul id="authorarchive-tabs" class="authorarchive-tabs add-menu-item-tabs">
<li <?php echo ( 'all' == $current_tab ? ' class="tabs"' : '' ); ?>>
<a class="nav-tab-link" data-type="tabs-panel-authorarchive-all" href="<?php if ( $nav_menu_selected_id ) echo esc_url( add_query_arg( 'authorarchive-tab', 'all', remove_query_arg( $removed_args ) ) ); ?>#tabs-panel-authorarchive-all">
<?php _e( 'View All' ); ?>
</a>
</li>
<li <?php echo ( 'admins' == $current_tab ? ' class="tabs"' : '' ); ?>>
<a class="nav-tab-link" data-type="tabs-panel-authorarchive-admins" href="<?php if ( $nav_menu_selected_id ) echo esc_url( add_query_arg( 'authorarchive-tab', 'admins', remove_query_arg( $removed_args ) ) ); ?>#tabs-panel-authorarchive-admins">
<?php _e( 'Admins' ); ?>
</a>
</li>
</ul>
Remember to assign the correct class names, IDs, and data attributes to the meta box elements; otherwise, the menu won’t work as expected.
Both add_query_arg
and remove_query_arg
functions set tab-specific values for the authorarchive-tabs
variable and remove unnecessary variables.
At this point, we have a meta box with defined tabs:
Our next step is to build the tabs’ HTML content.
Building the HTML Content for the Meta Box Tabs
You’ll want to follow the code in the previous section within the custom_menu_meta_box()
function. To build the content, use the following within the <div>
tag you wrote in the last section:
<div id="tabs-panel-authorarchive-all" class="tabs-panel tabs-panel-view-all <?php echo ( 'all' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); ?>">
<ul id="authorarchive-checklist-all" class="categorychecklist form-no-clear">
<?php
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $authors), 0, (object) array( 'walker' => $walker) );
?>
</ul>
</div>
<div id="tabs-panel-authorarchive-admins" class="tabs-panel tabs-panel-view-admins <?php echo ( 'admins' == $current_tab ? 'tabs-panel-active' : 'tabs-panel-inactive' ); ?>">
<ul id="authorarchive-checklist-admins" class="categorychecklist form-no-clear">
<?php
echo walk_nav_menu_tree( array_map('wp_setup_nav_menu_item', $admins), 0, (object) array( 'walker' => $walker) );
?>
</ul>
</div>
In short, each tab contains a list of checkboxes. The walk_nav_menu_tree() function prints the list using three arguments: $items
, $depth
, and $r
– all required.
The $items
array stores an array of admin users. The array_map()
function applies the wp_setup_nav_menu_item() function to $admins
and adds menu item properties to the array elements.
From here, we can add the finishing touches.
Adding a Submit Button
Most of the custom meta box is complete, although we still need to add a Submit button and a processing “spinner” icon.
Here’s a short piece of code that you can place straight after the previous block:
<p class="button-controls wp-clearfix">
<span class="list-controls">
<a href="<?php echo esc_url( add_query_arg( array( 'authorarchive-tab' => 'all', 'selectall' => 1, ), remove_query_arg( $removed_args ) )); ?>#authorarchive" class="select-all"><?php _e('Select All'); ?></a>
</span>
<span class="add-to-menu">
<input type="submit"<?php wp_nav_menu_disabled_check( $nav_menu_selected_id ); ?> class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="add-authorarchive-menu-item" id="submit-authorarchive" />
<span class="spinner"></span>
</span>
</p>
</div>
<?php
}
With this knowledge, you can add almost any functionality to your menus! Note that there’s also a public Gist of the plugin on GitHub that’s available to download for free.
Summary
A WordPress menu is a crucial aspect of your site. Because of this, the platform offers a native and powerful panel that will let you customize every menu on your site. However, it won’t provide everything you need by default.
Several screen options help you to add CSS tags and more. Also, installing a plugin will let you turn your native menus into mega menus and work with enhanced functionality to make yours more responsive (among other facets). Coding is also a possibility, and although it’s a challenging task for a novice coder, it’s something you can put together in the space of an afternoon.
Do you want to customize your WordPress menu, and if so, what approach are you going for? Share your thoughts and opinions in the comments section below!
When I click on Appearance, I don’t see anything about menus. :(