Hiding WordPress admin menu items by role can make the administration area easier to navigate for editors, authors, clients and other users who do not need every section of wp-admin.
WordPress provides native functions for removing items from the visible administration menu:
remove_menu_page()
remove_submenu_page()
These functions can be combined with roles or, preferably when permissions are involved, WordPress capabilities to create different administration experiences for different users.
For example, you could simplify the menu for users who cannot manage site options:
add_action( 'admin_menu', 'myplugin_customize_admin_menu', 999 );
function myplugin_customize_admin_menu() {
if ( current_user_can( 'manage_options' ) ) {
return;
}
remove_menu_page( 'tools.php' );
remove_menu_page( 'options-general.php' );
}
There is one rule that should guide the entire implementation:
Hidden menu item
≠
Revoked permission
Removing an item from the WordPress sidebar changes navigation. It does not automatically revoke the user’s capabilities or guarantee that the underlying screen cannot be reached another way.
This guide explains how to hide WordPress admin menu items by role or capability, remove submenus and plugin-created entries, build cleaner client dashboards and keep menu customization separate from real access control.
Why hide WordPress admin menu items?
A WordPress administration area can quickly become crowded.
A typical installation may contain:
Dashboard
Posts
Media
Pages
Comments
Appearance
Plugins
Users
Tools
Settings
Plugins can then add sections such as:
SEO
Analytics
Forms
Backups
Security
Cache
SMTP
Ecommerce
Reports
Marketing
Integrations
An administrator may legitimately need most of them. A content editor probably does not.
A client whose normal workflow consists of editing pages, publishing articles and reviewing form submissions may benefit from a much smaller administration menu.
Role-specific admin navigation can improve:
- clarity;
- navigation speed;
- editor onboarding;
- client usability;
- workflow consistency;
- the visibility of relevant tools;
- the overall cognitive load of wp-admin.
Before changing navigation, however, understand how WordPress permissions actually work. The distinction between roles and capabilities is covered in WordPress User Roles and Capabilities, Explained.
Menu visibility and access control are different
This is the most important concept in this guide.
Suppose you remove the Settings menu:
remove_menu_page( 'options-general.php' );
The user no longer sees Settings in the left-hand administration menu.
That does not mean remove_menu_page() should be treated as an authorization system.
The official WordPress documentation for remove_menu_page() describes it as a function for removing a top-level admin menu.
The same principle applies to submenus. The official remove_submenu_page() documentation explicitly notes that removing a submenu does not replace appropriate permission checks.
Think of the system as two separate layers:
Navigation layer
→ what the user sees
Authorization layer
→ what the user is allowed to access or modify
The difference is examined in more depth in Controlling WordPress Admin Page Visibility by Role.
WordPress roles are collections of capabilities
WordPress includes several default roles:
Administrator
Editor
Author
Contributor
Subscriber
Permissions, however, are fundamentally based on capabilities.
Examples include:
edit_posts
publish_posts
edit_others_posts
upload_files
manage_categories
manage_options
activate_plugins
install_plugins
edit_users
A role contains a collection of capabilities.
The official WordPress Roles and Capabilities documentation explains the permission model in detail.
This matters because custom roles can be created and plugins can modify the capabilities assigned to existing roles.
Prefer capability checks when the rule represents permission
You can inspect the current user’s roles directly:
$user = wp_get_current_user();
if ( in_array( 'editor', (array) $user->roles, true ) ) {
// Editor-specific interface customization.
}
That can be appropriate when the requirement genuinely concerns the presentation for a specific named role.
For permission-oriented logic, however, capabilities are normally more flexible:
if ( ! current_user_can( 'manage_options' ) ) {
// Customize the interface for users
// who cannot manage site options.
}
The official current_user_can() documentation covers the standard API for checking the current user’s capabilities.
For a deeper explanation of the distinction, see WordPress User Roles and Capabilities, Explained.
How to remove a top-level WordPress admin menu item
WordPress provides:
remove_menu_page( $menu_slug );
The function should be called on the admin_menu action.
For example:
add_action( 'admin_menu', 'myplugin_remove_comments_menu', 999 );
function myplugin_remove_comments_menu() {
remove_menu_page( 'edit-comments.php' );
}
This removes the Comments entry from the visible administration menu.
The official remove_menu_page() reference documents the expected menu slug and execution context.
Common WordPress admin menu slugs
Core WordPress menu items commonly use these slugs:
Dashboard
index.php
Posts
edit.php
Media
upload.php
Pages
edit.php?post_type=page
Comments
edit-comments.php
Appearance
themes.php
Plugins
plugins.php
Users
users.php
Tools
tools.php
Settings
options-general.php
These are the values normally passed to remove_menu_page().
Hide several WordPress admin menu items
You can remove several entries in the same callback:
add_action( 'admin_menu', 'myplugin_clean_admin_menu', 999 );
function myplugin_clean_admin_menu() {
remove_menu_page( 'edit-comments.php' );
remove_menu_page( 'tools.php' );
remove_menu_page( 'options-general.php' );
}
Without a condition, this affects every user for whom those menu items exist.
In most real projects, you will want to apply the changes selectively.
Hide menu items from users who cannot manage site options
A practical pattern is to preserve the normal administration menu for users who can manage site options and simplify it for everyone else:
add_action( 'admin_menu', 'myplugin_role_based_menu', 999 );
function myplugin_role_based_menu() {
if ( current_user_can( 'manage_options' ) ) {
return;
}
remove_menu_page( 'plugins.php' );
remove_menu_page( 'tools.php' );
remove_menu_page( 'options-general.php' );
}
The logic is simple:
User can manage_options
→ leave these menu items unchanged
User cannot manage_options
→ remove selected navigation entries
This is usually more adaptable than assuming every privileged user must have the literal administrator role.
Why use a late admin_menu priority?
Examples that remove administration menu entries often use a relatively late priority:
add_action(
'admin_menu',
'myplugin_customize_menu',
999
);
WordPress core and plugins register menu entries during the administration lifecycle. Your removal callback cannot remove a plugin menu that has not been registered yet.
A late priority can therefore be useful when modifying menu items created by third-party plugins.
This is particularly relevant to submenus, where the official remove_submenu_page() documentation notes that some entries may require the removal callback to run later.
Use admin_menu for admin menu customization
For normal administration menu manipulation, use:
admin_menu
For example:
add_action(
'admin_menu',
'myplugin_customize_menu',
999
);
The official remove_menu_page() documentation specifies the admin_menu action because the administration menu structure needs to exist before an entry can be removed.
How to remove a submenu item
Removing a child menu requires:
remove_submenu_page(
$menu_slug,
$submenu_slug
);
The first argument identifies the parent menu.
The second identifies the submenu.
For example:
add_action( 'admin_menu', 'myplugin_remove_submenus', 999 );
function myplugin_remove_submenus() {
remove_submenu_page(
'themes.php',
'theme-editor.php'
);
}
The official remove_submenu_page() reference documents the two required slugs.
Top-level menus and submenus use different functions
The distinction is straightforward:
remove_menu_page()
→ top-level admin menu
remove_submenu_page()
→ child menu beneath a parent
Using remove_menu_page() for a submenu is not the correct API.
Hide menu items specifically for Editors
Sometimes the requirement genuinely concerns a named role rather than a capability.
For example:
add_action( 'admin_menu', 'myplugin_editor_menu', 999 );
function myplugin_editor_menu() {
$user = wp_get_current_user();
if ( ! in_array( 'editor', (array) $user->roles, true ) ) {
return;
}
remove_menu_page( 'tools.php' );
}
This changes the visible menu specifically for users who have the Editor role.
It does not independently revoke any capabilities the Editor may possess.
Hide menu items specifically for Authors
add_action( 'admin_menu', 'myplugin_author_menu', 999 );
function myplugin_author_menu() {
$user = wp_get_current_user();
if ( ! in_array( 'author', (array) $user->roles, true ) ) {
return;
}
remove_menu_page( 'edit-comments.php' );
remove_menu_page( 'tools.php' );
}
Again, this is an interface rule rather than a security boundary.
Hide menu items for several roles
You can define a group of roles:
add_action( 'admin_menu', 'myplugin_limited_menu', 999 );
function myplugin_limited_menu() {
$user = wp_get_current_user();
$limited_roles = array(
'editor',
'author',
'contributor',
);
if (
! array_intersect(
$limited_roles,
(array) $user->roles
)
) {
return;
}
remove_menu_page( 'tools.php' );
remove_menu_page( 'options-general.php' );
}
This approach is useful when the interface requirement is explicitly role-based.
It also means you need to think about users who may hold more than one role. TheOneWP Multi Role Assignment is designed for environments where a user needs multiple WordPress roles.
Multiple roles complicate role-name logic
Suppose a user has:
Editor
+
another custom role
A simple condition such as:
in_array( 'editor', (array) $user->roles, true )
still matches that user.
The second role may grant capabilities that change what the user should actually be allowed to do.
This is one reason capability checks are usually a stronger foundation when the condition represents permission:
if ( ! current_user_can( 'manage_options' ) ) {
...
}
If a site has accumulated several custom roles, audit them before building a complex set of menu rules. See How to Audit User Roles on a WordPress Site.
Hide menu items using a custom capability
Custom capabilities can make complex permission structures easier to understand.
Imagine a plugin defines:
manage_company_settings
The menu customization can then follow that permission:
add_action( 'admin_menu', 'myplugin_company_menu', 999 );
function myplugin_company_menu() {
if ( current_user_can( 'manage_company_settings' ) ) {
return;
}
remove_menu_page( 'company-settings' );
}
If custom roles and capabilities need to be managed directly, TheOneWP Role Manager provides a dedicated interface for that layer.
Hide plugin-created admin menu items
Third-party plugins can register their own top-level menu pages.
To remove one, you need its actual menu slug.
Imagine a plugin registers:
add_menu_page(
'Reports',
'Reports',
'manage_options',
'company-reports',
'company_render_reports'
);
The relevant slug is:
company-reports
You can therefore remove the visible menu entry with:
remove_menu_page( 'company-reports' );
The visible label is not necessarily the value required by remove_menu_page(). You need the registered menu slug.
For the opposite process, creating your own menu entries, see How to Add Custom Admin Menu Items in WordPress.
How to find a plugin menu slug
One reliable method is to inspect the plugin code and find its call to:
add_menu_page()
or:
add_submenu_page()
You can also inspect the administration URL.
A plugin page may use:
/wp-admin/admin.php?page=company-reports
In that example, the menu slug is likely:
company-reports
When you control the plugin itself, use unique, stable slugs from the beginning.
Inspecting the WordPress menu structure
During development, WordPress’s global menu arrays can help identify unfamiliar menu entries:
$GLOBALS['menu']
$GLOBALS['submenu']
For example, in a controlled development environment:
add_action( 'admin_menu', 'myplugin_debug_menu', 999 );
function myplugin_debug_menu() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
error_log(
print_r(
$GLOBALS['menu'],
true
)
);
}
The same can be done for submenus:
add_action( 'admin_menu', 'myplugin_debug_submenu', 999 );
function myplugin_debug_submenu() {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
error_log(
print_r(
$GLOBALS['submenu'],
true
)
);
}
Use this as a development technique, not as permanent production logging.
Build a simplified client dashboard
Consider a site where administrators need:
Dashboard
Posts
Media
Pages
Comments
Appearance
Plugins
Users
Tools
Settings
SEO
Forms
Backups
Security
Editors may need only:
Dashboard
Posts
Media
Pages
Comments
SEO
Authors may need:
Dashboard
Posts
Media
Role-aware navigation can provide those different experiences without changing the entire administration menu for every user.
Example: simplified menu for Editors
add_action( 'admin_menu', 'myplugin_simplify_editor_menu', 999 );
function myplugin_simplify_editor_menu() {
$user = wp_get_current_user();
if ( ! in_array( 'editor', (array) $user->roles, true ) ) {
return;
}
remove_menu_page( 'tools.php' );
}
The exact entries you remove should reflect the real site and the Editor’s responsibilities.
Do not copy a generic list of hidden menus without first checking which entries the role can already access and which tools the user actually needs.
Correct permissions at registration are better than cleanup
If you are developing the custom admin page yourself, assign the correct capability when registering it.
The official add_menu_page() documentation states that its capability argument determines whether the page is included in the menu for the current user.
Consider this custom page:
add_menu_page(
'Private Reports',
'Reports',
'read',
'private-reports',
'myplugin_render_private_reports'
);
If only users with a custom reporting capability should access it, registering the page broadly and hiding it later is unnecessary.
A better implementation would be:
add_menu_page(
'Private Reports',
'Reports',
'view_company_reports',
'private-reports',
'myplugin_render_private_reports'
);
The rendering callback should also verify the required capability:
function myplugin_render_private_reports() {
if ( ! current_user_can( 'view_company_reports' ) ) {
wp_die(
esc_html__(
'You are not allowed to access this page.',
'myplugin'
)
);
}
echo '<div class="wrap">';
echo '<h1>Private Reports</h1>';
echo '</div>';
}
For the complete custom admin page architecture, see How to Add a Custom Admin Page in WordPress.
Submenus can use different capabilities
A plugin can expose several administration screens with different permissions:
Company
├── Dashboard
├── Reports
└── Settings
For example:
add_submenu_page(
'company',
'Reports',
'Reports',
'view_company_reports',
'company-reports',
'company_render_reports'
);
add_submenu_page(
'company',
'Settings',
'Settings',
'manage_company_settings',
'company-settings',
'company_render_settings'
);
The official add_submenu_page() documentation confirms that its capability argument determines whether the submenu is included for the current user.
This is cleaner than registering every screen with a broad capability and attempting to reconstruct the permission structure later through menu removal.
Protect custom admin pages separately
If access matters, the underlying page should enforce the required capability.
function myplugin_render_private_page() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die(
esc_html__(
'You are not allowed to access this page.',
'myplugin'
)
);
}
echo '<div class="wrap">';
echo '<h1>Private Settings</h1>';
echo '</div>';
}
The same principle applies to:
form handlers
AJAX actions
REST API endpoints
exports
imports
database operations
file operations
settings updates
The broader strategy is covered in Restricting WordPress Features by User Role.
Do not use CSS to hide admin menus
You could technically write:
#menu-settings {
display: none;
}
But that only changes presentation in the browser.
The menu node still exists in the generated document, and the underlying page is unaffected.
If the objective is to manipulate WordPress administration navigation, use the WordPress menu APIs:
remove_menu_page()
remove_submenu_page()
Do not use JavaScript as an access-control mechanism
The same problem applies to JavaScript:
document.querySelector(
'#menu-settings'
).remove();
This changes the browser interface after the page has loaded.
It does not revoke permissions and should not be used as a security mechanism.
Hiding a menu item from a specific user
Sometimes interface customization is user-specific rather than role-specific.
For example:
add_action( 'admin_menu', 'myplugin_user_menu', 999 );
function myplugin_user_menu() {
if ( 42 !== get_current_user_id() ) {
return;
}
remove_menu_page( 'tools.php' );
}
Hardcoding user IDs is rarely ideal for reusable plugins, but it demonstrates that menu visibility can depend on conditions other than roles.
A production implementation might instead use:
user metadata
custom capabilities
plugin settings
organization membership
workflow configuration
Capability-based rules usually scale better
Imagine you initially create rules for:
Administrator
Editor
Author
Later, plugins introduce custom roles such as:
Shop Manager
SEO Manager
Course Instructor
Support Agent
Client Manager
Role-name logic now requires additional maintenance.
Capability-oriented rules can instead ask:
Can this user manage site options?
Can this user edit other users' posts?
Can this user manage this plugin?
Can this user view reports?
This usually adapts more naturally as the site evolves.
Managing custom roles
For more complex projects, define responsibilities first.
For example:
Content Editor
→ editorial content
SEO Manager
→ SEO configuration and metadata
Store Manager
→ products and orders
Site Administrator
→ site-wide configuration
Then assign appropriate capabilities to those responsibilities.
TheOneWP Role Manager provides a dedicated interface for managing WordPress roles and their capabilities.
Users with multiple responsibilities
A user may need responsibilities from more than one role.
For example:
Content Editor
+
SEO Manager
TheOneWP Multi Role Assignment supports users who need multiple WordPress roles.
When menu customization follows capabilities rather than rigid role-name assumptions, navigation can better reflect the combined permissions of those users.
Hiding and reorganizing are different problems
Sometimes a menu item should not disappear. It may simply be in the wrong place.
A crowded administration area can often be improved by:
reordering items
grouping related tools
renaming unclear labels
moving frequently used items upward
moving technical tools downward
The TheOneWP Admin Menu Organizer is designed for this navigation layer.
When should you hide an item?
Hide an item when it is irrelevant to the user’s workflow.
Reorder it when it remains useful but its current position creates friction.
For example:
Content editor never uses a technical tool
→ hide it
Content editor uses SEO constantly
→ keep it easy to reach
Administrator occasionally uses backups
→ keep the menu available
A useful administration interface is not necessarily the one with the fewest links. It is the one that makes relevant tasks easy to find.
Access Manager and menu visibility solve different problems
Once the requirement changes from:
make this menu cleaner
to:
this user must not access this functionality
the problem becomes access control.
TheOneWP Access Manager addresses that layer, while Admin Menu Organizer addresses navigation structure.
The distinction is useful:
Admin Menu Organizer
→ navigation and presentation
Access Manager
→ access control
Role Manager
→ roles and capabilities
The Admin Menu and Admin Bar are different
WordPress contains two separate navigation systems that are sometimes confused:
Admin Menu
→ left sidebar inside wp-admin
Admin Bar
→ toolbar displayed across the top
Removing an item from one does not automatically remove it from the other.
If the objective is to customize toolbar nodes, TheOneWP Disable Admin Bar Items addresses that separate interface.
Hiding the entire Admin Bar
Some user groups may not need the toolbar at all.
TheOneWP Hide Admin Bar provides a dedicated way to control that behavior.
Do not confuse hiding the Admin Bar with customizing the left-hand wp-admin menu. They are independent interfaces.
Use the correct capability for the feature
Do not automatically use manage_options for every custom administration feature.
Choose a capability that represents the actual operation.
Examples include:
Editing posts
→ edit_posts
Editing other users' posts
→ edit_others_posts
Publishing posts
→ publish_posts
Managing site options
→ manage_options
Editing users
→ edit_users
Managing a custom plugin
→ purpose-built custom capability
The closer the capability matches the responsibility, the easier the permission model is to understand and maintain.
Hide an entire custom plugin section
Suppose a custom plugin uses:
company-dashboard
as its top-level menu slug.
You can remove that navigation entry conditionally:
add_action( 'admin_menu', 'myplugin_hide_company_menu', 999 );
function myplugin_hide_company_menu() {
if ( current_user_can( 'manage_company' ) ) {
return;
}
remove_menu_page( 'company-dashboard' );
}
The plugin itself should still use manage_company to protect the pages and actions that require that permission.
What happens to child pages?
Removing the visible top-level parent removes that navigation path from the sidebar.
It should not be interpreted as automatically revoking access to every underlying page.
If those pages are independently registered with capabilities the user possesses, their authorization still depends on those capabilities.
The rule remains:
Menu hierarchy
≠
Permission hierarchy
Do not rely on hidden URLs
A hidden URL is not a protected URL.
Administration routes may still be discovered through:
- browser history;
- bookmarks;
- links from other screens;
- documentation;
- network requests;
- plugin code;
- known WordPress URL patterns.
If access matters, protect the underlying page or operation with capabilities.
Direct URL testing is essential
After changing menu visibility, manually test the underlying URL while logged in as the affected user.
For example:
/wp-admin/admin.php?page=company-settings
Ask two separate questions:
Should this user see the menu item?
Should this user be allowed to access the page?
The answers are not necessarily the same.
Test role-specific menu changes properly
At minimum, test the resulting administration interface using the roles that actually exist on the site.
That may include:
Administrator
Editor
Author
Contributor
custom roles
multi-role users
Do not test only with the primary Administrator account.
Different users can receive different capabilities, and plugins may modify those capabilities.
Test custom roles
Production sites frequently contain custom roles such as:
Shop Manager
SEO Manager
Course Instructor
Membership Manager
Support Agent
Client Editor
If menu customization depends on roles or capabilities, those users need to be included in testing.
If the existing role structure is unclear, start with How to Audit User Roles on a WordPress Site.
Test users with multiple roles
If your site allows multiple roles, test combinations rather than isolated roles only.
A user with:
Editor
+
SEO Manager
may possess a different capability set from a conventional Editor.
Capability-based menu rules generally handle these combinations more predictably.
Test third-party plugin updates
Plugins can change:
menu slugs
menu hierarchy
capabilities
registration timing
submenu structure
If your code removes a third-party plugin menu by its internal slug, verify the customization after significant plugin updates.
Test WordPress updates
Core administration behavior can evolve over time.
After significant WordPress updates, verify that:
- expected menu items remain hidden;
- required menu items remain visible;
- direct access behaves as expected;
- custom role behavior remains correct;
- plugin-created entries still use the expected structure.
Do not hide workflow dependencies
Before removing an item, determine whether the user needs it indirectly.
An editor may need Media even when most images are uploaded through the Block Editor.
A store manager may need access to customer-related user screens.
An SEO specialist may need access to custom post types or taxonomy screens.
Design navigation around actual responsibilities rather than assumptions based solely on role names.
Use the principle of least privilege
Menu customization works best when it sits on top of a sensible permission model.
The general sequence should be:
User responsibilities
↓
Required capabilities
↓
Appropriate role or roles
↓
Relevant admin navigation
Not:
Grant broad permissions
↓
Hide links to make the interface look restricted
For broader role-based restrictions, see Restricting WordPress Features by User Role.
A practical implementation pattern
For a conventional client site, you might use:
add_action( 'admin_menu', 'myplugin_customize_menu_by_capability', 999 );
function myplugin_customize_menu_by_capability() {
/*
* Preserve the normal menu for users
* who manage site configuration.
*/
if ( current_user_can( 'manage_options' ) ) {
return;
}
/*
* Remove navigation that is irrelevant
* to the intended workflow.
*/
remove_menu_page( 'tools.php' );
remove_menu_page( 'options-general.php' );
}
Sensitive custom functionality should still enforce its own capability requirements independently.
A more granular capability-based implementation
add_action( 'admin_menu', 'myplugin_granular_menu', 999 );
function myplugin_granular_menu() {
if ( ! current_user_can( 'manage_options' ) ) {
remove_menu_page( 'options-general.php' );
}
if ( ! current_user_can( 'activate_plugins' ) ) {
remove_menu_page( 'plugins.php' );
}
if ( ! current_user_can( 'edit_users' ) ) {
remove_menu_page( 'users.php' );
}
if ( ! current_user_can( 'edit_theme_options' ) ) {
remove_menu_page( 'themes.php' );
}
}
In many default WordPress configurations, some of these entries may already be absent because the user lacks the capability used when WordPress registered them. The example illustrates the relationship between capabilities and menu customization rather than suggesting that every site needs all four removal rules.
Do not remove menu items WordPress already excludes
WordPress already considers capabilities when creating administration menus.
The official add_menu_page() reference and add_submenu_page() reference both include a required capability argument.
If the current user does not have the required capability, the custom page is not included in that user’s menu.
Therefore, do not add unnecessary removal logic simply because a role normally lacks access to a screen already protected by WordPress.
Menu removal is primarily an interface tool
The strongest use case for remove_menu_page() and remove_submenu_page() is interface customization.
Examples include:
- removing irrelevant navigation for clients;
- simplifying wp-admin for content teams;
- hiding rarely used tools from everyday workflows;
- creating role-specific administration experiences;
- reducing clutter on plugin-heavy websites;
- keeping important tasks easier to find.
Common mistake: treating menu hiding as security
This is the most important mistake to avoid:
Menu disappeared
↓
User must no longer have access
That conclusion is incorrect.
Navigation and authorization are separate concerns.
If access must be denied, use capabilities on the underlying page and on every privileged operation associated with it.
Common mistake: hiding menus with CSS
CSS can hide an element visually:
#menu-settings {
display: none;
}
But it does not change permissions or WordPress’s server-side menu structure.
Use WordPress’s menu APIs for menu manipulation.
Common mistake: removing menus with JavaScript
JavaScript can remove a node after the page loads, but that is still a browser-side presentation change.
It can also produce visual flashes while the page initializes.
Use server-side WordPress APIs instead.
Common mistake: checking only the Administrator role
This:
in_array(
'administrator',
(array) $user->roles,
true
)
can be valid when the rule explicitly concerns the Administrator role.
When the real question is whether the user can perform an operation, use the corresponding capability instead:
current_user_can( 'manage_options' )
Common mistake: using visible labels instead of slugs
A menu labelled:
Analytics
might internally use:
company-analytics-dashboard
The visible label is not necessarily the value required by remove_menu_page().
Use the actual registered menu slug.
Common mistake: removing a submenu with remove_menu_page()
Use:
remove_submenu_page(
'parent-slug',
'submenu-slug'
);
for child entries.
Common mistake: running the removal too early
Your callback cannot remove a plugin menu that has not been registered yet.
If necessary, use a later admin_menu priority:
add_action(
'admin_menu',
'myplugin_customize_menu',
999
);
Common mistake: forgetting direct links
A hidden admin page may still be linked from:
dashboard widgets
admin notices
plugin screens
documentation
emails
browser bookmarks
custom admin pages
Always test the real authorization boundary separately from sidebar visibility.
Document your menu rules
Role-specific administration customization can become difficult to understand as a site grows.
Document:
Menu item
Affected users
Condition or capability
Whether access is also restricted
Reason for the customization
For example:
Custom Reports
Visible when:
current_user_can( 'view_company_reports' )
Reason:
Only reporting users need this navigation.
Security:
The underlying page also checks
view_company_reports.
Review menu rules when responsibilities change
A configuration that works today may become inappropriate after:
- adding an ecommerce team;
- introducing an SEO specialist;
- adding custom post types;
- installing a membership system;
- creating custom roles;
- changing the client’s internal responsibilities.
Admin navigation should evolve with the site’s operating model.
Audit the underlying role system periodically
Menu customization becomes unreliable when nobody knows what the site’s roles actually permit.
Periodically review:
users
roles
capabilities
custom roles
unused accounts
multi-role users
plugin-created capabilities
The full process is covered in How to Audit User Roles on a WordPress Site.
A complete role-aware menu strategy
A maintainable administration model can be visualized as:
Responsibilities
↓
Roles and capabilities
↓
Page authorization
↓
Action authorization
↓
Menu visibility
↓
Menu organization
Each layer has a separate responsibility.
If permissions are wrong, fix permissions.
If permissions are correct but users see irrelevant navigation, customize visibility.
If the correct items are visible but poorly arranged, reorganize the menu.
Production checklist
- Use
admin_menufor normal wp-admin menu manipulation. - Use a later priority when you need to modify entries registered later by plugins.
- Use
remove_menu_page()for top-level menu entries. - Use
remove_submenu_page()for child entries. - Identify menu entries by their registered slugs.
- Prefer capabilities when the condition represents permission.
- Use direct role checks when the interface rule genuinely depends on a named role.
- Account for users with multiple roles.
- Test custom roles.
- Do not use CSS as an access-control mechanism.
- Do not use JavaScript as an access-control mechanism.
- Do not assume a hidden menu item is inaccessible.
- Protect sensitive custom admin pages with capabilities.
- Protect form handlers independently.
- Protect AJAX actions independently.
- Protect REST endpoints independently.
- Test direct admin URLs.
- Test every relevant user type.
- Test users with multiple roles where applicable.
- Review third-party menu rules after plugin updates.
- Review customizations after significant WordPress updates.
- Keep navigation aligned with real user workflows.
- Separate menu organization from access control.
- Manage the Admin Bar separately from the wp-admin sidebar.
- Audit roles and capabilities periodically.
Related guides
- Controlling WordPress Admin Page Visibility by Role
- WordPress User Roles and Capabilities, Explained
- How to Audit User Roles on a WordPress Site
- Restricting WordPress Features by User Role
- How to Add Custom Admin Menu Items in WordPress
- How to Add a Custom Admin Page in WordPress
Related TheOneWP features
Admin Menu Organizer helps reorganize WordPress administration navigation when the objective is to simplify the interface rather than modify permissions.
Access Manager addresses the access-control layer when users should actually be prevented from reaching particular functionality.
Role Manager provides control over the role and capability structure behind those permissions.
Multi Role Assignment supports users who need responsibilities from more than one WordPress role.
Disable Admin Bar Items handles individual navigation nodes in the separate WordPress Admin Bar.
Hide Admin Bar controls the visibility of the toolbar itself when it is not required for a user’s workflow.
Final recommendation
Use role-specific WordPress admin menus to improve navigation, not as a substitute for permissions.
For top-level items, use remove_menu_page(). For child entries, use remove_submenu_page(). Run normal menu customization through admin_menu, and use an appropriately late priority when you need to modify entries registered by other plugins.
When a rule represents actual permission, prefer WordPress capabilities or purpose-built custom capabilities instead of relying exclusively on role names.
Most importantly, keep these two questions separate:
Should the user see this menu item?
Should the user be allowed to access this functionality?
The first is a navigation decision. The second is an authorization decision.
A well-designed WordPress administration environment uses both layers together: capabilities protect sensitive functionality, while role-aware menu customization removes irrelevant complexity and gives users a clearer workspace for the tasks they actually perform.

