Two canonical tags on the same page. WordPress settings look correct. So why is the live HTML different?
If you manage WordPress sites for clients, you've probably hit this: the SEO plugin settings say one thing, but the actual rendered <head> says another. Multiple plugins, a theme, and a page builder can all end up touching the same tag.
Here's the debugging approach I use before touching anything in production.
1. Check the final rendered <head>, not just the settings screen
View the page source of the live page. The WordPress admin settings show what a plugin wants to output — not necessarily what actually reaches the browser. Something later in the request can override, duplicate, or strip it.
2. Identify every component that hooks into wp_head
add_action( 'wp_head', 'my_callback', 10 );
Every plugin, theme, and page builder that touches SEO output does this somewhere. On a stack with 20-30 plugins, more than one usually will.
3. Trace the callback and its priority
Priority determines execution order, not who "wins" — two callbacks can both print a canonical tag, and the browser just renders both. Query Monitor (free plugin) lists every wp_head callback with its priority and source file, which turns this from guesswork into a five-minute check.
4. Find which plugin/theme actually owns the source file
Once you have the file path from Query Monitor, you know the real source — not just the plugin whose settings screen you assumed was responsible.
5. Test the suspected removal on staging first
Before removing a competing hook in production, verify the change on staging. A tag that looks redundant might be load-bearing for something you haven't checked yet: hreflang, a verification tag, a plugin-specific integration.
Why this matters for migrations
The same method applies when migrating between SEO plugins. "The new plugin imported the settings" and "the live page still outputs everything it used to" are two different questions. Before switching, I'd capture the rendered head of a representative sample of pages — homepage, posts, archives, WooCommerce products, local pages — then diff the same pages after.
Anything that silently disappears — canonical, robots directives, OG/Twitter tags, JSON-LD, verification tags, hreflang — is worth investigating. Text changing usually isn't a problem. A tag that vanishes usually is.
I'm curious how other people managing multi-plugin WordPress stacks handle this today: disable candidates one by one, rely on Query Monitor, inspect hooks manually, or something else entirely?
I build Livada SEO, a WordPress SEO plugin. This exact debugging process is what led us to build tag-level attribution directly into the plugin — happy to go into more detail if useful.
Top comments (0)