WordPress SEO

A technical SEO practitioner's guide to WordPress — the default settings that hurt you, how the core sitemap and canonical handling actually work, why you run exactly one SEO plugin, and the duplicate-content sources WordPress creates on its own.

First published: Jun 27, 2026 · Last updated: Jul 25, 2026 · Advanced
demand #1 in CMS#3 in Platform SEO#46 in Technical SEO#63 on the site

WordPress is SEO-capable, not SEO-finished. It self-canonicalizes posts since version 2.9 and ships a native XML sitemap since 5.5 — but its defaults also leave ?p=123 permalinks, attachment pages, date/tag/author archives, feeds, and internal search results all indexable, and a single Settings → Reading checkbox can silently block the whole site. The fixes that actually matter: set /%postname%/ before publishing, run exactly one SEO plugin (Yoast, Rank Math, or AIOSEO — never two, the wp_head conflict produces duplicate metadata), noindex thin archives instead of disallowing them, and keep the sitemap to canonical indexable URLs only. WordPress 6.4+ disables attachment pages on new installs by default — redirecting straight to the file, not the parent post — but existing sites keep them on and must migrate manually. Google has never said WordPress ranks better or worse than any other CMS — content and links decide that, not the platform.

TL;DR — WordPress is SEO-capable, not SEO-finished. It self-canonicalizes singular posts since version 2.9 and ships a native XML sitemap since 5.5 — but defaults leave ?p=123 permalinks, attachment pages, date/tag/author archives, feeds, and ?s= search pages all indexable, and the Settings → Reading checkbox can silently block the whole site. The fixes that move the needle: /%postname%/ before publishing, exactly one SEO plugin (the wp_head conflict from two is real), noindex thin archives rather than disallowing them, and a sitemap of canonical indexable URLs only. WordPress 6.4+ disables attachment pages by default on new installs — redirecting to the file itself, not the parent post; existing sites keep them enabled and migrate by hand. Google has never said WordPress is better or worse for SEO than any other CMS. Evidence for this claim WordPress added core XML sitemaps in 5.5 and attachment-page redirects for new sites in 6.4. Scope: Core version history; existing sites can retain prior attachment behavior. Confidence: high · Verified: WordPress 5.5 XML sitemaps WordPress 6.4 attachment pages

WordPress is SEO-capable, not SEO-finished

The honest framing is somewhere between the two marketing claims you usually hear. WordPress is not “SEO-friendly out of the box” in any complete sense — but it also isn’t bad for SEO. It gives you a strong, controllable foundation and then leaves a pile of indexable cruft turned on by default. The whole job is knowing which defaults to change and which auto-generated URLs to suppress.

And to be clear up front: Google has never said WordPress ranks better or worse than any other CMS. As Google’s documentation puts it, “if you’re using a CMS such as WordPress, Wix, or Blogger, it’s likely that your CMS has already made a sitemap available to search engines” — the platform is treated like any other. Rankings come from content and links, not from the logo in your admin bar. Evidence for this claim Google says common CMS platforms often generate sitemaps and does not prescribe a CMS-specific ranking advantage. Scope: Google sitemap guidance; absence of a CMS ranking advantage is an editorial inference from platform-neutral requirements. Confidence: medium · Verified: Google: Build and submit a sitemap

The defaults that hurt — and why

The “Discourage search engines from indexing this site” checkbox (Settings → Reading) writes a site-wide noindex and a restrictive virtual robots.txt. It’s the first thing I check on any WordPress audit, because it’s the single setting that can silently zero out an entire site’s indexing — usually left on from staging.

The ?p=123 default permalink gives no topical signal and isn’t a clean URL. Switch to /%postname%/ — and do it before publishing. On an established site, changing the permalink structure means URL changes; WordPress will auto-301 the old numeric URLs for standard post types, but custom post types and pages don’t always redirect cleanly, so test. I’d avoid baking the category into the permalink (/%category%/%postname%/): the day you reorganize taxonomy you trigger a mass URL change and throw away ranking history for no proportional benefit.

Attachment pages are the WordPress-specific gotcha people forget. Every media upload historically spawned a standalone URL containing just the file and some auto-metadata — thin pages that can cannibalize the real ones. WordPress 6.4 changed the default so new installs disable attachment pages entirely — a request to one now redirects straight to the file itself, not the parent post. Existing (upgraded) sites keep attachment pages enabled; there’s no Settings-screen toggle for this, only wp option set wp_attachment_pages_enabled 0 via WP-CLI or editing the option directly on wp-admin/options.php. In practice most site owners never touch that option and instead handle it the plugin way: noindex the attachment page, or better, redirect it to the parent post via your SEO plugin. Don’t assume an older site inherited the WordPress 6.4 default; it didn’t.

Archives, feeds, and search pages. By default WordPress generates indexable category archives, tag archives, date archives, author archives, paginated archive pages (?page=2), feed URLs (/feed/), attachment pages, and internal search result pages (/page=search, i.e. ?s=). That’s the canonical list of WordPress duplicate-content sources, and almost none of it was a decision you made.

Duplicate content WordPress creates on its own

Worth stating plainly because it surprises people: WordPress manufactures structural duplicate content by default. The recurring sources:

SourceExampleTypical fix
Category archives/category/news/Keep, or noindex if thin
Tag archives/tag/wordpress/Usually noindex (thin, overlapping)
Author archives/author/admin/Noindex on single-author sites
Date archives/2023/04/Noindex (almost always thin)
Pagination/page/2/Self-referential canonical (not page 1)
Feed URLs/feed/Noindex feeds
Attachment pages/photo-of-cat/Redirect to parent via SEO plugin (WP 6.4+ redirects new installs to the file itself instead)
Search results/?s=keywordNoindex

The fix is almost never to panic about a penalty — Google consolidates duplicates to a canonical rather than penalizing structural duplication. The fix is to noindex the thin stuff and keep the sitemap clean. And a critical distinction: noindex ≠ no-crawl. A noindexed page must stay crawlable so Google can actually read the noindex. If you disallow it in robots.txt instead, Google can’t see the directive — which is why you noindex thin archives rather than blocking them.

The XML sitemap: core vs. plugin

WordPress 5.5 (August 2020) added a native XML sitemap at /wp-sitemap.xml. It’s real, but barebones. It dumps in all public post types, all public taxonomies, and author archives — meaning it happily lists exactly the thin pages you want out of the index. It has no image-sitemap support and limited control. So in practice most sites use the sitemap from Yoast or Rank Math instead, which lets you include/exclude specific post types and taxonomies and keep the file to canonical, indexable URLs. Yoast disables the core sitemap and replaces it; that’s expected.

Two things the sitemap won’t do for you: Google ignores <priority> and <changefreq> entirely (per Google’s own docs), and WordPress does not submit the sitemap to Google for you — you submit it in Search Console and Bing Webmaster Tools, and you can list it via a Sitemap: directive in robots.txt for passive discovery. The 50,000-URL / 50MB limit from the spec still applies; split into a sitemap index past that.

Canonical handling: core, plugin, and the conflict trap

Core has output rel=canonical via rel_canonical() since WordPress 2.9 (2009) — singular posts and pages self-canonicalize. WordPress 4.6 didn’t add the tag; it refactored the function to use the filterable wp_get_canonical_url(), which is what people usually mean when they say “canonical since 4.6.” That’s a good baseline, but core doesn’t handle custom post types consistently across themes, doesn’t add canonicals on 404s, and doesn’t resolve URL-variation duplicates (?utm_source=, www vs. non-www, trailing slashes) on its own. SEO plugins replace the core output with more comprehensive handling: custom post type canonicals, self-referential pagination canonicals (not pointing page 2+ at page 1 — a mistake that deindexes your deeper pages), cross-domain canonical for syndication, and per-page overrides.

Here’s the trap that ties the whole plugin question together: the canonical tag set by your SEO plugin is the authoritative signal — but if your theme also injects a title tag or its own SEO meta, you get a conflict. Some theme frameworks (Genesis, Thesis) emit their own SEO tags. When you activate an SEO plugin, disable the theme-level SEO, and inspect the rendered <head> to confirm exactly one canonical, one title, one meta description.

One SEO plugin. Never two.

This deserves its own heading because it’s the most common self-inflicted WordPress SEO wound. Never run two SEO plugins simultaneously. Yoast, Rank Math, and AIOSEO all hook into wp_head() to write the title, meta description, canonical, Open Graph/Twitter tags, robots meta, and JSON-LD. Run two and they both fire — duplicate meta descriptions, duplicate (and contradictory) canonical tags, conflicting Open Graph, and conflicting sitemaps. Search Console will flag the duplicate metadata. Pick one and fully uninstall the other (deactivating leaves database entries behind).

As for which one — they all cover the core tasks; the choice is use-case and budget:

  • Yoast SEO — the largest install base, the familiar traffic-light scoring, great for beginners and content teams that want a guided workflow. (WooCommerce schema is a paid add-on.)
  • Rank Math — the most generous free tier: unlimited focus keywords, redirect manager, 404 monitoring, GSC + GA4 integration, and a strong schema builder (16+ types free). My pick for developers and power users.
  • All in One SEO (AIOSEO) — strong WooCommerce integration, internal-link assistant, good local SEO. Suits agencies and large stores.

One caution on Yoast’s green lights: a higher Yoast score doesn’t mean better rankings. It’s a heuristic for basic on-page formatting — keyword presence, title length, readability proxies. A red-light post routinely outranks an all-green one. Content quality, intent match, authority, and links matter far more.

Schema: what WordPress does and doesn’t output

Core WordPress outputs essentially nothing useful for rich results — clean HTML Google can parse, but no JSON-LD. As Google notes, “if you use a CMS, such as Wix, WordPress, or Shopify, you might not be able to edit your HTML directly… you may be able to install a plugin that allows you to specify structured data.” That’s the path:

  • Yoast auto-adds Organization/Person, WebSite (with SearchAction), WebPage, BreadcrumbList, and Article schema in JSON-LD.
  • Rank Math adds those plus 16+ schema types in the free tier (FAQ, HowTo, Product, Review, Event…) and a builder for custom types.
  • WooCommerce alone outputs basic Open Graph product metadata but no Product JSON-LD — you need Yoast WooCommerce SEO (paid) or Rank Math Pro for full Product schema with price, availability, and review aggregate.

WooCommerce, briefly

WooCommerce stacks more SEO surface on top of standard WordPress. The recurring issues: the /product/ and /product-category/ URL bases (removable, with redirects on existing sites), product variations creating near-duplicates, and — the big one — faceted navigation generating thousands of thin filter-combination URLs. Handle facets the same way you’d handle them anywhere: ideally JS-based filtering with no URL change, otherwise rel=canonical to the base category and/or noindex, follow on filter pages (with crawling allowed so the directive is seen). Shop and category pagination wants self-referential canonicals, and Google deprecated rel=prev/next back in 2019 — harmless if present, but don’t rely on it. Faceted nav has its own deep treatment in the Ecommerce SEO pillar.

robots.txt and Core Web Vitals — two quick notes

WordPress serves a virtual robots.txt (it’s not a file on disk) defaulting to disallowing /wp-admin/ while allowing admin-ajax.php. Drop a physical file at the root and it overrides the virtual one entirely; SEO plugins let you edit the virtual version from the dashboard. The classic mistake is disallowing /wp-content/, which blocks CSS/JS/images and breaks rendering — don’t.

On performance: the “WordPress is slow” complaint is a configuration problem, not a core problem. LCP issues trace mostly to TTFB (cheap shared hosting, no opcode cache) and unoptimized hero images; INP issues to JavaScript bloat from page builders (Elementor, Divi); CLS to images without dimensions and web fonts without font-display: swap. Lightweight themes (GeneratePress, Kadence, Astra) plus a caching plugin, a CDN, and modern image formats get a well-built WordPress site through Core Web Vitals comfortably. The detail lives in the Web Performance cluster.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin an expert quote first.