How to Add a Custom Admin Notice in WordPress

Admin notices are the coloured banners at the top of dashboard pages — WordPress itself uses them for update alerts, plugin activation messages, and configuration warnings. Adding your own is straightforward and only takes a few lines.

Problem: How do you display a notice in the WordPress admin — for example, after a plugin action or settings save — that optionally can be dismissed?

Solution: Hook into admin_notices and echo a <div> with the appropriate CSS classes. For dismissible notices add the is-dismissible class and handle persistence via a user meta option or transient.

Hook into admin_notices and echo your markup. WordPress handles the placement automatically:

add_action( 'admin_notices', 'my_plugin_admin_notice' );

function my_plugin_admin_notice() {
    // Only show to admins on the plugins page
    if ( ! current_user_can( 'manage_options' ) ) return;
    if ( get_current_screen()->id !== 'plugins' ) return;

    $type    = 'notice-warning'; // notice-info | notice-success | notice-warning | notice-error
    $message = __( 'My Plugin requires the API key to be configured before it can work.', 'textdomain' );
    $link    = ''
               . __( 'Configure now', 'textdomain' ) . '';
    ?>
    <div class="notice <?php echo esc_attr( $type ); ?> is-dismissible">
        <p><?php echo wp_kses_post( $message . ' ' . $link ); ?></p>
    </div>
    <?php
}

To show a notice only once — for example, right after plugin activation — use a transient as a flag:

register_activation_hook( __FILE__, function() {
    set_transient( 'myplugin_activated_notice', true, 60 );
} );

add_action( 'admin_notices', function() {
    if ( ! get_transient( 'myplugin_activated_notice' ) ) return;
    delete_transient( 'myplugin_activated_notice' );
    ?>
    <div class="notice notice-success is-dismissible">
        <p><?php esc_html_e( 'My Plugin activated successfully!', 'textdomain' ); ?></p>
    </div>
    <?php
} );

NOTE: The is-dismissible CSS class only adds the close button UI — it does not persist the dismissal across page loads. To permanently dismiss a notice per user, save a flag with update_user_meta() and check it before rendering.