How to Fix WordPress Menu Highlighting for Custom Post Types
If you’ve ever created a custom post type (CPT) in WordPress, you may have noticed an issue where your navigation menu incorrectly highlights the Blog menu item instead of the correct one. This happens because WordPress assigns the current_page_parent
class to the blog menu by default when viewing single posts—including custom post types.
In this guide, we’ll show you how to fix this issue by dynamically assigning the correct menu item highlighting for custom post types using a simple PHP function in functions.php
.
Use Case: Why Fixing Menu Highlighting Matters?
Let’s say you have two custom post types:
event
(for listing events)initiative
(for showcasing initiatives)
You also have corresponding menu items:
- Events (
/events/
) - All Initiatives (
/all-initiatives/
)
However, when you click on an event, the navigation does not highlight the “Events” menu item. Instead, the Blog menu gets highlighted because WordPress treats it as a regular post.
We’ll fix this by ensuring the correct menu item gets the current_page_item
class whenever a user views an event or initiative post or their archives.
The Code Solution
Add the following code to your functions.php
file:
function fix_custom_post_type_menu_highlight($classes, $item) {
// Define custom post types and their corresponding menu item slugs
$menu_mappings = [
'event' => 'events', // Custom post type 'event' should highlight 'events' menu item
'initiative' => 'all-initiatives', // Custom post type 'initiative' should highlight 'all-initiatives' menu item
];
foreach ($menu_mappings as $post_type => $menu_template) {
if (is_singular($post_type) || is_post_type_archive($post_type)) {
// Remove incorrect highlighting from the Blog menu item
if ($item->object_id == get_option('page_for_posts')) {
$classes = array_diff($classes, ['current_page_parent']);
}
// Ensure we don't add duplicate classes
$classes = array_filter($classes, function($class) {
return !in_array($class, ['current_page_item', 'current-menu-item']);
});
// Apply 'current_page_item' to the correct menu item
if (stripos($item->url, '/' . $menu_template) !== false) {
$classes[] = 'current_page_item';
}
}
}
return $classes;
}
add_filter('nav_menu_css_class', 'fix_custom_post_type_menu_highlight', 10, 2);
How This Code Works
1. Define the Custom Post Type Mappings
$menu_mappings = [
'event' => 'events',
'initiative' => 'all-initiatives',
];
- This array maps custom post types (
event
,initiative
) to their corresponding menu item slugs (events
,all-initiatives
). - Update this array to include more CPTs and menu items as needed.
2. Check if the User is on a CPT Page
if (is_singular($post_type) || is_post_type_archive($post_type)) {
- This checks if the user is viewing a single post from a CPT or the CPT archive page.
3. Remove Incorrect Highlighting from the Blog Menu
if ($item->object_id == get_option('page_for_posts')) {
$classes = array_diff($classes, ['current_page_parent']);
}
- If the menu item is the Blog page, we remove the
current_page_parent
class (which WordPress applies incorrectly).
4. Prevent Duplicate Classes
$classes = array_filter($classes, function($class) {
return !in_array($class, ['current_page_item', 'current-menu-item']);
});
- This ensures we don’t add multiple active classes, keeping the HTML clean.
5. Apply the Correct Highlighting to the CPT Menu Item
if (stripos($item->url, '/' . $menu_template) !== false) {
$classes[] = 'current_page_item';
}
- This checks if the menu item URL contains the correct slug (e.g.,
/events/
) and applies thecurrent_page_item
class.
Final Output: Expected Behavior
After adding this function:
- When viewing an event post or archive, the “Events” menu item is highlighted.
- When viewing an initiative post or archive, the “All Initiatives” menu item is highlighted.
- The Blog menu item is no longer highlighted incorrectly.
Conclusion
This solution ensures that your WordPress menu correctly highlights custom post types instead of mistakenly marking the Blog menu as active. It’s a reusable function, so you can easily extend it by adding more CPTs to $menu_mappings
.
Try it out and make your WordPress menus more intuitive!
About the author
Alok Jain
As a Frontend Developer and Founder, I blend technical skills with entrepreneurial drive. Skilled in crafting intuitive user interfaces, I bridge design and development for seamless digital experiences. Beyond work, I'm passionate about Philately, sharing my collection, and connecting with fellow enthusiasts in both tech and stamp collecting communities.