TL;DR
Add WordPress meta tags through one clear owner. Usually that means one SEO plugin controls titles, descriptions, canonicals, robots tags, Open Graph tags, and Twitter card output.
- Inspect rendered source before adding custom tags so you do not create duplicates.
- Write custom metadata for high-value pages instead of relying only on templates.
- Validate search snippets, canonical URLs, robots directives, and social previews after cache clears.
Decide Which System Owns Metadata
The safest WordPress setup has one metadata owner. Usually that is an SEO plugin. Sometimes it is custom theme code or a static export pipeline. The weak setup is a mixture: the theme prints a title, the SEO plugin prints another title, a page builder adds Open Graph tags, and a custom snippet adds a second canonical URL.
Before adding anything, inspect a few pages. View the rendered source and look for title, meta description, canonical URL, robots tag, Open Graph title, Open Graph image, and Twitter card tags. If any tag appears twice with different values, fix ownership before writing new tags.
Plugin Workflow for Most Sites
For most WordPress sites, an SEO plugin is the practical way to add meta tags. It gives editors page-level fields, global templates, archive controls, sitemap integration, and social preview settings. The important part is avoiding overlap. If the SEO plugin controls Open Graph tags, disable Open Graph output from the theme or social sharing plugin.
Set templates for posts, pages, products, categories, and custom post types. Then override important pages manually. A service page, homepage, product category, and high-value article usually need human-written metadata. Template-generated descriptions are acceptable for low-risk pages but not for the pages that decide conversions or search visibility.
When Custom Code Makes Sense
Custom metadata code can be reasonable for a small controlled site, a headless setup, a custom plugin, or a static WordPress export. If you use functions.php, keep the logic simple and avoid hard-coded assumptions that break on archives, pagination, search pages, and custom post types.
Do not paste random wp_head snippets without checking plugin output first. WordPress already has title handling, canonical behavior, feed links, and other head output. A custom snippet should add a missing controlled tag, not duplicate a feature that already exists.
Validation Checklist
- One title tag appears in rendered source.
- One meta description appears and matches the page intent.
- One canonical URL points to the preferred public URL.
- Robots directives match the indexing decision.
- Open Graph and Twitter card tags use the same intended title, description, URL, and image.
- Important templates are tested after cache is cleared.
- Search Console and social preview tools confirm the deployed output.
Frequently Asked Questions
Can I add meta tags through functions.php?
Yes, but it is easy to duplicate plugin output. Use functions.php only when you understand the existing head output and need a small controlled addition.
Does every page need a custom meta description?
Every important indexable page should have a useful description. Low-value archives may be better noindexed or handled through templates, depending on the site.
Why is Google showing a different description?
Search engines may rewrite snippets when page content better matches the query. A strong meta description still matters because it gives a preferred summary and helps consistency across tools.
Open Graph and Social Images Need Real Assets
Open Graph tags control how pages appear in many social apps and messaging previews. A useful setup includes og:title, og:description, og:url, og:type, and og:image. For articles, the image should represent the article or tool clearly, not a generic abstract background.
If the wrong image appears, check the page source, image URL accessibility, cache, dimensions, and whether another plugin writes a second Open Graph block. Social platforms cache previews aggressively, so fix the HTML first, clear site cache, then rescrape using the platform preview debugger where available.