WordPress’s navigation menu system is built around named locations, abstract slots in your theme that can be assigned any menu from the Menus admin screen. When a theme registers a location, it appears in Appearance → Menus under “Menu Settings”, and any menu the user builds can be dragged or assigned to that slot. Rendering the assigned menu in a template is then a single function call. This separation of structure from content is what makes WordPress menus flexible, the theme defines where menus go, and the site owner decides what’s in each menu without touching any code.
The Code
Add this to your functions.php. It uses register_nav_menus(), the plural form, which accepts a key-value array of location slugs and their human-readable labels. Registering multiple locations in one call is more efficient than calling register_nav_menu() individually for each.
Choosing Location Slugs
Location slugs should be lowercase, hyphenated identifiers that describe the location’s purpose and position, not its content. primary, footer, sidebar, mobile, and legal are all good slugs because they describe where the menu appears. Avoid slugs like main-menu or top-links which describe content rather than location, if the menu’s content changes, a content-describing slug becomes misleading.
Rendering a Menu
The commented-out example at the bottom of the snippet shows the standard wp_nav_menu() call used to render a registered location in a template file. Key arguments to understand:
theme_location references the registered slug. This is what links the template output to the menu assigned in the admin. container and container_class control the wrapping HTML element, set container to false to remove the wrapper entirely if your theme’s markup doesn’t need it. depth controls how many levels of child items are rendered, setting it to 1 is appropriate for flat footer menus where dropdowns would be inappropriate. fallback_cb set to false prevents WordPress from falling back to rendering all pages as a menu when no menu is assigned to the location, which can cause unexpected output on new installs.
Checking If a Menu Is Assigned
Before rendering a menu location in a template, it’s good practice to check whether a menu has actually been assigned to it using has_nav_menu( 'location-slug' ). This prevents the container element from being rendered empty when the location has no assigned menu, keeping your HTML clean and avoiding layout shifts on sites still being built out.
Block Theme Menus
In full site editing block themes, navigation is managed through the Navigation block in the Site Editor rather than through register_nav_menus() and wp_nav_menu(). This snippet is appropriate for classic themes and hybrid themes. If you’re building on a block theme, use the Navigation block’s built-in menu management instead.
add_action( 'after_setup_theme', function() {
register_nav_menus( [
'primary' => __( 'Primary Navigation', 'nahnu-snippets' ),
'footer' => __( 'Footer Navigation', 'nahnu-snippets' ),
'legal' => __( 'Legal Links', 'nahnu-snippets' ),
'mobile' => __( 'Mobile Navigation', 'nahnu-snippets' ),
] );
} );
// Example: render the footer menu in a template
// wp_nav_menu( [
// 'theme_location' => 'footer',
// 'menu_class' => 'footer-nav',
// 'container' => 'nav',
// 'container_class'=> 'footer-nav-wrap',
// 'depth' => 1,
// 'fallback_cb' => false,
// ] );
