WordPress makes schema deceptively easy to add and surprisingly easy to get wrong. A plugin will switch it on in a click — and quietly ship generic, sometimes conflicting markup. Here's the honest breakdown of the plugin route, where it stops being enough, and when hand-written JSON-LD is worth the effort.
For a simple site, an SEO plugin is a reasonable first move. Rank Math, Yoast, and AIOSEO all emit baseline structured data — Article, Breadcrumb, Organization — with little effort. If you just need rich-result eligibility on a blog, that's often enough, and I'd never talk someone out of starting there.
Plugins optimize for "works on every site," which means they rarely fit your site. They struggle with custom service offerings, multi-location businesses, and precise entity linking. Worse, run two SEO plugins — or a plugin plus a theme that also emits schema, which is common on Avada and other builder themes — and you get duplicate, conflicting markup that confuses crawlers. At that point the plugin is working against you, and no toggle fixes it.
Once schema matters to your revenue — local visibility, AI citations, rich results that actually convert — hand-written JSON-LD wins. You emit one clean @graph through the theme (a wp_head hook) or a tag manager, tailored to your real content, with proper entity linking and zero plugin conflicts. This very site does exactly that: its structured data is hand-coded, not plugin-generated.
@graphEmitted via the theme — no duplicate or conflicting blocks.I'll audit what your plugins are emitting, kill the conflicts, and build custom JSON-LD that fits your site — whether you're on a standard theme, Avada, or a page builder.