OctaneAudit
Guides

WordPress SEO Audit: The Essential Technical Checklist

A practical WordPress SEO audit: indexing settings, sitemaps, archives, canonicals, plugin conflicts and performance, with the exact place to check each one.

OCOctaneAudit Team11 min read
Guides

WordPress SEO Audit: The Essential Technical Checklist

WordPress sites fail SEO audits for a predictable set of reasons. The CMS itself is search-friendly out of the box, but every theme, plugin and settings change adds a layer that can override what core does. Most of the problems we find are not exotic. They are a checkbox, a duplicate plugin, or an archive type nobody remembered existed.

This checklist is the order we work through on a WordPress site. It assumes you have admin access and, ideally, WP-CLI on the server. If you want the platform-agnostic version first, start with our technical SEO audit checklist and come back here for the WordPress specifics.

Step 1: Confirm the site is allowed to be indexed

Start here because nothing else matters if this is wrong.

Go to Settings > Reading and look at "Search engine visibility". If "Discourage search engines from indexing this site" is ticked, WordPress outputs a robots meta tag with noindex, nofollow on every page. This setting is often ticked on staging and carried over when the database is copied to production.

From the command line:

# 1 means indexing is allowed, 0 means "Discourage search engines" is on
wp option get blog_public

Then check the rendered HTML of the homepage and one post. You are looking for exactly one robots meta tag and no noindex unless you put it there on purpose:

curl -s https://www.example.com/ | grep -i '<meta name=.robots'
curl -sI https://www.example.com/ | grep -i x-robots-tag

The header check matters. Security plugins, hosting panels and CDN rules can add an X-Robots-Tag header that never shows in the page source.

Step 2: Check site URLs, HTTPS and the preferred host

In Settings > General, the "WordPress Address (URL)" and "Site Address (URL)" should both use https:// and the host you want indexed (with or without www, but consistently).

Then test that every variant redirects in a single hop to the preferred version:

for u in http://example.com http://www.example.com https://example.com; do
  curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" "$u/"
done

Every line should return 301 pointing directly at https://www.example.com/ (or your preferred host). Two hops, such as HTTP to HTTPS and then non-www to www, waste crawl and slow the first visit. Fix it at the server or CDN level rather than with a redirect plugin, so the redirect happens before PHP loads.

Leftover http:// asset URLs in the database can be found with wp search-replace and its --dry-run flag; take a backup before running it for real.

Settings > Permalinks should be set to "Post name" or a custom structure that produces clean, readable URLs. Plain URLs like /?p=123 still work, but they give users and search engines nothing to go on.

wp rewrite structure
# Expected output similar to: /%postname%/

If you change the permalink structure on an established site, every old URL needs a 301 to its new equivalent. WordPress redirects some old post URLs on its own, but do not rely on that. Export the old URL list from your sitemap or a crawl before the change, and test a sample afterwards.

Step 4: Sitemaps and robots.txt

Since WordPress 5.5, core generates an XML sitemap at /wp-sitemap.xml. Most SEO plugins (Yoast SEO, Rank Math, All in One SEO and others) disable the core sitemap and provide their own, usually at /sitemap_index.xml.

The audit questions:

  1. Is there exactly one sitemap system active? Load both /wp-sitemap.xml and /sitemap_index.xml. If both return valid sitemaps, two systems are running.
  2. Is the submitted sitemap the live one? In Search Console, open the Sitemaps report and confirm the submitted URL matches the active sitemap and was read successfully.
  3. Does it contain only indexable URLs? No redirects, no noindex pages, no 404s, no tag pages you have chosen to noindex.

WordPress serves a virtual robots.txt if no physical file exists. The default is minimal and safe:

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php

Sitemap: https://www.example.com/wp-sitemap.xml

What to look for in a customized one:

  • No Disallow: /wp-content/ or /wp-includes/. Googlebot needs your CSS and JavaScript to render pages. Blocking theme and plugin assets is an old habit that still shows up.
  • A Sitemap: line pointing at the sitemap you actually use.
  • No Disallow on URLs you are trying to noindex. If a URL is blocked, Google cannot see the noindex. Our guide on robots.txt vs noindex vs nofollow covers why this combination fails.

Step 5: Find and control thin archive pages

WordPress creates several archive types automatically. Each can generate dozens or thousands of low-value URLs.

Archive typeExample URLTypical recommendation
Tag archives/tag/blue-widgets/Noindex unless tags are curated and have real content
Category archives/category/guides/Index; add an intro paragraph and treat as a hub
Author archives/author/admin/Noindex or disable on single-author sites
Date archives/2026/06/Noindex or disable; rarely useful for search
Attachment pages/blue-widget-photo/Redirect to the parent post or the file
Internal search/?s=widgetsNoindex; never link to search results
Paginated archives/category/guides/page/3/Index with a self-referencing canonical

Attachment pages deserve special attention. Every uploaded image can get its own HTML page containing little more than the image. WordPress 6.4 added an option that disables attachment pages, and it is off by default on new installs, but sites created before 6.4 keep the old behavior unless someone changed it. Most SEO plugins also have a setting to redirect attachment URLs to the file or parent post. Check with:

wp option get wp_attachment_pages_enabled
# 1 means attachment pages are still served

If you are not using an SEO plugin for robots directives, or need a rule the plugin cannot express, the wp_robots filter (available since WordPress 5.7) is the clean way to add noindex to specific archive types:

add_filter( 'wp_robots', function ( $robots ) {
    if ( is_tag() || is_date() || is_search() ) {
        $robots['noindex'] = true;
        $robots['follow']  = true;
    }
    return $robots;
} );

Put this in a small site-specific plugin or a child theme, not the parent theme, so updates do not remove it. If an SEO plugin already manages robots meta, configure it there instead. Two systems writing the same tag is how sites end up with conflicting directives.

Step 6: Canonicals, titles and duplicate tags

WordPress core outputs a rel="canonical" tag on single posts and pages. SEO plugins replace it and add canonicals to archives. Themes sometimes add their own as well.

View the source of a post, a page, a category archive and the homepage, and count:

  • rel="canonical" tags: exactly one per page.
  • <title> elements: exactly one.
  • meta name="description": at most one.
  • og: tags: one set, not two.

Duplicates almost always mean a theme with built-in SEO features plus a plugin, or two SEO plugins active at once. Check the active plugin list:

wp plugin list --status=active --fields=name,version

Also confirm canonicals point at the URL that is actually served. A canonical to the http:// or non-www version, left over from before a migration, tells Google to prefer a URL that redirects.

For WooCommerce stores and other sites with filters or sorting parameters, check that parameterized URLs canonicalize to the clean version. The parallel post on canonical tags goes deeper on edge cases.

Step 7: Structured data conflicts

Many themes output their own schema, and so does every major SEO plugin. The result is often two Article or two Organization entities with different names, logos or authors.

Run a post and the homepage through the Rich Results Test or the Schema Markup Validator and look for duplicated types. Pick one source of truth, usually the SEO plugin, and turn off schema output in the theme or other plugins. A typical clean result for a blog post looks like this:

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "WordPress SEO Audit: The Essential Technical Checklist",
  "datePublished": "2026-06-16",
  "author": { "@type": "Person", "name": "Jane Doe" },
  "publisher": { "@type": "Organization", "name": "Example Co" }
}

One entity per type, consistent names, and no properties describing content that is not on the page.

Step 8: Performance and Core Web Vitals

WordPress performance problems usually come from what is added on top of core, not core itself.

Plugins and assets

  • Count active plugins and ask what each one does. The number matters less than what each loads. A form plugin that enqueues its scripts and styles on every page, even those without a form, costs every visitor.
  • Use Query Monitor on a staging copy to see slow database queries, the number of HTTP API calls made during page generation, and which scripts each plugin enqueues.
  • Look for page builders loading full asset libraries on pages that use none of their widgets.

Caching and hosting

  • Full-page caching for anonymous visitors, either at the host, a caching plugin or the CDN. Without it every request runs PHP and database queries.
  • A persistent object cache (Redis or Memcached) on sites with WooCommerce, memberships or heavy plugins.
  • A supported PHP 8.x version. Check under Tools > Site Health. Old PHP versions are slower and stop receiving security fixes.
  • Time to First Byte under 800 milliseconds for cached pages. If it is higher, the problem is hosting or caching, and front-end tweaks will not fix it.

Images and LCP

Recent WordPress releases help here. Core has added native lazy-loading (5.5), skipped lazy-loading for the first content image and added fetchpriority="high" to it (6.3), and supports WebP and AVIF uploads. Themes and page builders can still undo this by lazy-loading hero images with JavaScript or using CSS background images for the hero.

Check the LCP element on your main templates in PageSpeed Insights. If it is lazy-loaded or a CSS background, that is your first fix. Our guide to improving LCP below 2.5 seconds walks through each phase.

The final pass is about what Google finds once it can crawl efficiently.

  • Orphan posts. Compare the sitemap against a crawl. Posts in the sitemap that the crawler cannot reach through links get little internal authority.
  • Broken internal links after slug changes. Fix the link at the source rather than relying on a redirect.
  • Category structure. Categories make good topical hubs when each has an intro and links to its key posts. A site with 40 categories and three posts each is harder to navigate than one with eight well-filled categories.
  • Old redirect chains. Redirect plugins accumulate rules for years. Export them, find chains (A to B to C) and point every rule straight to the final URL.

Keep it from regressing

A WordPress site changes every time a plugin updates, a theme is swapped or someone edits a setting. The same audit run six months later often finds new problems: a plugin update that re-enabled its sitemap, a new theme that added duplicate schema, a staging copy pushed live.

Re-run the checks in Steps 1, 4 and 6 after every major plugin or theme change. If you would rather not do that manually, AI Monitoring checks your key pages daily and alerts you when robots directives, canonicals or Core Web Vitals change.

Summary

  • Check Settings > Reading and the rendered robots meta and X-Robots-Tag header before anything else.
  • Run one sitemap system, submit that one in Search Console, and keep /wp-content/ crawlable in robots.txt.
  • Noindex or disable thin archives: tags, dates, author pages on single-author sites, attachment pages and internal search.
  • One canonical, one title, one schema source per page. Duplicates almost always mean a theme and a plugin competing.
  • Fix performance at the caching and plugin level first, then make sure the LCP image is not lazy-loaded.
SharePostLinkedInFacebook

Get Your SEO Audit

Every issue in this article, checked on your site by an auditor and delivered as a prioritized roadmap within 48-72 hours.

See pricing

Related articles