How to Hide, Customize, and Add Items to the WordPress Admin Bar

The WordPress admin bar — the black toolbar that appears at the top of every page for logged-in users — is convenient during development but can break layouts, confuse clients, and expose information that should stay behind the scenes. At the same time it is also a useful quick-access surface: adding a direct link to the theme customizer, a frequently edited custom post type, or a staging/production environment switcher saves time on every editing session. WordPress provides clean hooks to hide the bar entirely for selected roles, remove specific default nodes, and add entirely new items — without touching the core or a plugin. The mechanism is straightforward: show_admin_bar(false) removes the bar globally, the wp_before_admin_bar_render action removes individual nodes via $wp_admin_bar->remove_node(), and admin_bar_menu adds new ones via $wp_admin_bar->add_node(). All three approaches are covered below, along with a practical pattern for showing the bar only to administrators while keeping it hidden from editors, authors, and subscribers.

Problem: The WordPress admin bar is visible to all logged-in users, breaks your theme's fixed header, and shows menu items that are irrelevant or distracting for non-administrator roles. You want to hide it for certain users and optionally add your own quick-access links.

Solution: Use show_admin_bar(false) for non-admin users, remove unwanted default nodes with remove_node(), and add custom nodes with add_node() on the admin_bar_menu hook.

Hide the admin bar for everyone except administrators:

<?php
add_action( 'after_setup_theme', 'control_admin_bar_visibility' );

function control_admin_bar_visibility() {
    if ( ! current_user_can( 'manage_options' ) ) {
        show_admin_bar( false );
    }
}

Remove specific default nodes (the WordPress logo menu, comments, and the "Howdy" account menu):

<?php
add_action( 'wp_before_admin_bar_render', 'remove_default_admin_bar_nodes' );

function remove_default_admin_bar_nodes() {
    global $wp_admin_bar;
    $wp_admin_bar->remove_node( 'wp-logo' );      // WordPress logo & menu
    $wp_admin_bar->remove_node( 'comments' );     // comments counter
    $wp_admin_bar->remove_node( 'my-account' );   // "Howdy, Username"
    $wp_admin_bar->remove_node( 'search' );       // front-end search bar
}

Add a custom top-level node with child links — for example, quick access to a custom post type and the Customizer:

<?php
add_action( 'admin_bar_menu', 'add_custom_admin_bar_nodes', 100 );

function add_custom_admin_bar_nodes( $wp_admin_bar ) {
    // Top-level parent node
    $wp_admin_bar->add_node( [
        'id'    => 'my-shortcuts',
        'title' => 'Quick Links',
        'href'  => false,
    ] );

    // Child: edit events CPT
    $wp_admin_bar->add_node( [
        'id'     => 'my-shortcuts-events',
        'parent' => 'my-shortcuts',
        'title'  => 'Events',
        'href'   => admin_url( 'edit.php?post_type=event' ),
    ] );

    // Child: open Customizer
    $wp_admin_bar->add_node( [
        'id'     => 'my-shortcuts-customizer',
        'parent' => 'my-shortcuts',
        'title'  => 'Customizer',
        'href'   => admin_url( 'customize.php' ),
    ] );
}

NOTE: The full list of default admin bar node IDs is not documented in one place in the Codex. The quickest way to inspect them is to add a temporary var_dump( $wp_admin_bar->get_nodes() ) inside a wp_before_admin_bar_render callback and look at the id keys. Remove the debug output before deploying to a live site.