Open Appearance → Themes on a site that is a few weeks behind. There is a count badge on the Themes menu item and a box on the theme card: "New version available. Update now."
It reads like the mildest notice in WordPress. It is the one I most want off a client's screen, because of what the button does when the parent theme was customised directly. No child theme, edits made straight into the theme, which describes a very large number of the sites any of us inherit. Clicking update now replaces those files with the vendor's. Custom header, template edits, functions.php, replaced with defaults. The notice does not warn about that, and the client reading it has no way to know.
Most guides on this keyword hand you one line and stop. The line usually looks like this:
add_filter('site_transient_update_themes', '__return_null'); // please don't
That does not hide the notice. It empties the transient WordPress stores theme update results in, so core stops knowing that any theme has an update. The notice disappears as a side effect, because there is nothing left to render. You have not cleaned a dashboard, you have blinded the site, and the next developer to inherit it finds a quiet admin sitting on top of a year of unapplied releases. If you find that filter in a client site, take it out.
Here is what actually prints the notice. On the themes grid (themes.php) the theme cards are rendered from JS, and the update data comes from wp_prepare_themes_for_js(), which sets hasUpdate and update per theme. So you filter that:
add_filter('wp_prepare_themes_for_js', function ($themes) {
foreach ($themes as $slug => $theme) {
$themes[$slug]['hasUpdate'] = false;
$themes[$slug]['update'] = false;
}
return $themes;
});
The notice is gone from the grid. The update check still runs, which is the point. Now load the screen and the count badge is still on the Themes menu item.
That badge never came from the notice. It is built by wp_get_update_data(), which counts pending core, plugin, theme and translation updates and feeds both the admin menu bubble and the toolbar. Second hook:
add_filter('wp_get_update_data', function ($data) {
$data['counts']['themes'] = 0;
$data['counts']['total'] = 0;
$data['title'] = '';
return $data;
});
And if you run multisite, the network Themes screen is a list table, not a grid, with its own update rows printed by wp_theme_update_rows() on admin_init at priority 20. Third hook, unhooked from an earlier priority on the same hook:
add_action('admin_init', function () {
remove_action('admin_init', 'wp_theme_update_rows', 20);
}, 1);
Three code paths for one notice, and the published guides cover at most one of them. Then you want the same treatment for plugin update notices, and core, and each has its own removal. By the time you have covered them all you have a mu-plugin, and the mu-plugin has to travel to every site you build. Miss a hook on one and that client gets a half cleaned dashboard.
I tested the settings-panel version with WP Adminify Pro instead. 20 second demo below.
What the theme update notice actually costs on a client site:
- A count badge plus an update box on a screen the client visits to change nothing
- The button behind it is destructive on any directly-customised parent theme, and it does not say so
- The notice is aimed at whoever does the updates, which on agency builds is not the person reading it
- It cannot be dismissed, so it never clears until someone updates, and the someone who clicks is usually the wrong someone
What changed after enabling Hide Admin Notices in Adminify Pro:
- One toggle under Productivity covers the theme update notice for every admin at once
- The Themes count badge clears with it, no separate
wp_get_update_datafilter to remember - The same module handles the plugin and core notice pile-up, so the admin opens to work rather than a stack of banners
- The update check keeps running, so a maintenance report still sees every pending theme update
- Survives WordPress updates, no snippet to carry between sites
The caveat I will not skip: hiding the notice does not update the theme. Your version is unchanged and any security release you are behind on is still unapplied. This is right when the update has an owner and a schedule (you, your agency, a managed host, an automation with rollback) and when a child theme exists so the update is survivable when it does get run. It is wrong on a site nobody maintains, where that box is the only signal anyone will ever get. Decide who owns updates first. Then hide the notice. And whatever you decide, do not null the transient.
Step-by-step doc: https://wpadminify.com/docs/adminify/productivity/hide-admin-notices
How do you handle theme update notices on sites you maintain for other people: filter wp_prepare_themes_for_js, hide them with a plugin, or leave them visible and accept the risk?