The WordPress admin dashboard is composed of widget-like panels called “meta boxes”. You can add your own — to display plugin stats, a quick-links panel, a support contact section — or remove the default ones to clean up the interface for clients.
Problem: How do you add a custom information widget to the WordPress admin dashboard — for example, showing recent entries, post counts, or data from an external API?
Solution: Use wp_add_dashboard_widget() inside a wp_dashboard_setup action hook, providing a handle, a title, and a callback that outputs the widget's HTML content.
Add a custom dashboard widget:
add_action( 'wp_dashboard_setup', 'register_my_dashboard_widgets' );
function register_my_dashboard_widgets() {
wp_add_dashboard_widget(
'my_plugin_stats', // Widget ID (slug)
__( 'My Plugin Stats', 'td' ), // Title
'render_my_dashboard_widget', // Callback
'configure_my_dashboard_widget' // Optional control/settings callback
);
}
function render_my_dashboard_widget() {
$count = wp_count_posts( 'portfolio' )->publish;
echo '<p>' . sprintf(
esc_html__( 'You have %d published portfolio items.', 'td' ),
$count
) . '</p>';
echo '<p><a href="' . esc_url( admin_url( 'edit.php?post_type=portfolio' ) ) . '">'
. esc_html__( 'Manage Portfolio', 'td' ) . '</a></p>';
}
function configure_my_dashboard_widget() {
// Settings form (shown when the user clicks "Configure")
if ( isset( $_POST['my_widget_option'] ) ) {
update_option( 'my_widget_option', sanitize_text_field( $_POST['my_widget_option'] ) );
}
$value = get_option( 'my_widget_option', 'default' );
echo '<label>' . esc_html__( 'Display mode:', 'td' ) . '
<input type="text" name="my_widget_option" value="' . esc_attr( $value ) . '">
</label>';
}
Remove default dashboard widgets (useful for client sites):
add_action( 'wp_dashboard_setup', 'remove_default_dashboard_widgets' );
function remove_default_dashboard_widgets() {
remove_meta_box( 'dashboard_right_now', 'dashboard', 'normal' ); // At a Glance
remove_meta_box( 'dashboard_activity', 'dashboard', 'normal' ); // Activity
remove_meta_box( 'dashboard_quick_press', 'dashboard', 'side' ); // Quick Draft
remove_meta_box( 'dashboard_primary', 'dashboard', 'side' ); // WordPress News
remove_meta_box( 'woocommerce_dashboard_status','dashboard', 'normal' ); // WooCommerce Status
}
NOTE: Dashboard widget positions are stored in user meta, so each user can rearrange them independently. If you want to force a specific layout for all users, hook into get_user_option_screen_layout_dashboard and set column counts accordingly.