Scan WordPress posts and pages for broken heading hierarchies and safely rewrite them back to a correct H2-first outline.
- Requires: WordPress 6.0+, PHP 7.4+
- Tested up to: WordPress 7.0
- Stable tag: 0.2.0
- License: GPL-2.0-or-later
If you've switched themes and inherited a site where the previous author used H4 in place of H2 (to compensate for large default heading sizes), Heading Cleaner helps you fix the entire site without editing every post by hand.
The plugin:
- Scans all posts and pages (including drafts and private posts) for body headings whose top level is not
H2. - Computes a level-shift that promotes the highest-rank heading back to
H2while preserving relative hierarchy. - Shows a before/after outline preview so you can sanity-check each post.
- Applies fixes individually or in bulk, via
wp_update_post()— every change creates a native WordPress revision you can roll back from the Revisions screen.
Works with both Gutenberg block content and Classic/HTML content. The post title H1 is never touched.
Posts that need manual judgement — such as those containing an in-body <h1>, hierarchy gaps (e.g. H2 then H4 with no H3), or headings inside reusable blocks — are flagged for review and not auto-fixed.
- Upload the
heading-cleanerfolder to/wp-content/plugins/. - Activate the plugin through the Plugins screen.
- Open Tools → Heading Cleaner and click Scan site.
Yes. Every apply writes via wp_update_post, which creates a native WordPress revision. Use the standard Revisions screen on the post to roll back.
No. Reusable blocks (core/block) and FSE templates are flagged but not rewritten in this version.
Headings emitted by page builders live outside post_content in a form this plugin cannot safely rewrite, so they are ignored.
- Link the post ID in each row to the live post (or preview URL for drafts).
- Show "View in editor" on every row, including auto-fixable ones, so the user can still open a post for manual editing instead of applying the automatic shift.
- Uninstall now iterates every site on multisite installs and uses
delete_post_meta_by_keyso the postmeta cache is busted after cleanup. - Add a
build.shscript that produces a distributable zip.
- Initial release.