WordPress SEO Checklist 2026 (Technical + On-Page)
WordPress SEO checklist: technical setup, on-page optimisation, Core Web Vitals, schema markup, and ongoing maintenance for agencies and freelancers.
A complete WordPress SEO checklist for 2026 covering technical setup, on-page optimisation, Core Web Vitals, schema markup, and the ongoing maintenance tasks agencies most often skip.
Most WordPress SEO checklists are padded with obvious advice. This one skips the basics and focuses on the technical and structural items that actually move rankings - the things agencies miss on client audits, or that get set up once and never revisited.
Work through it in order. Technical issues block everything else.
Technical SEO foundation
1. Verify the site is indexable
Go to Settings > Reading and confirm "Discourage search engines from indexing this site" is unchecked. This box gets left checked after development/staging work constantly. Check it on every new client site before anything else.
Verify with:
https://yourdomain.com/robots.txt
The default WordPress robots.txt should allow all crawlers. If you see Disallow: /, Google cannot index the site.
2. Confirm HTTPS is active and consistent
Every page must load over HTTPS with no mixed content warnings. Run the site through https://www.whynopadlock.com/ or open browser dev tools on the Network tab and filter by HTTP.
Also check:
http://redirects tohttps://(301, not 302)- Both
wwwand non-wwwredirect to a single canonical version - The canonical version matches
WP_HOMEinwp-config.php
Mixed content and redirect chains both dilute PageRank and signal poor technical setup to Google.
3. Set permalink structure
Go to Settings > Permalinks. Use /%postname%/ (post name only, no dates) for most sites. Date-based URLs (/%year%/%monthnum%/%postname%/) are appropriate for news sites but hurt evergreen content because the date in the URL signals to users that the content may be outdated.
Do not change permalink structure on a live site without setting up proper 301 redirects from old URLs.
4. Submit an XML sitemap
Most SEO plugins generate a sitemap automatically. Confirm:
- The sitemap URL (usually
/sitemap.xmlor/sitemap_index.xml) returns valid XML - It includes all your important pages, posts, and category archives
- It excludes paginated pages (
?page=2), tag archives, author pages (unless they have unique content), and login/admin pages
Submit the sitemap in Google Search Console under Indexing > Sitemaps.
5. Configure robots.txt
The default WordPress robots.txt is usually fine for standard sites. Add disallow rules for:
User-agent: * Disallow: /wp-admin/ Disallow: /wp-includes/ Disallow: /wp-login.php Disallow: /?s= Disallow: /search/ Allow: /wp-admin/admin-ajax.php
Block the internal search (?s=) to prevent Google indexing potentially infinite thin-content search results pages.
6. Check for crawl errors in Search Console
In Google Search Console > Coverage, look for:
- Excluded - noindex: pages that are excluded by
noindextags (intentional is fine; accidental is a problem) - Server errors (5xx): PHP errors or timeouts that Google hits during crawl
- Not found (404): broken internal links consuming crawl budget
- Redirect errors: redirect loops or chains longer than 3 hops
On-page SEO
7. Set a custom title and meta description for every page
Install an SEO plugin (Yoast, Rank Math, or SEOPress) and fill in the SEO title and meta description for every post, page, and archive. The SEO title should:
- Include the target keyword near the start
- Be under 60 characters (to avoid truncation in SERPs)
- Be unique - no two pages on the site should have the same title
Meta descriptions do not directly affect rankings but dramatically affect click-through rate. Write them as ad copy, not keyword lists.
8. Use one H1 per page
Every page should have exactly one <h1> that matches or closely reflects the SEO title. WordPress themes sometimes add extra H1s (in the site header logo, or in featured image captions) - check with browser dev tools.
9. Use headings hierarchically
H2s structure the main sections; H3s structure subsections within H2s. Do not skip heading levels (H2 directly to H4). Google uses heading structure to understand content hierarchy - it affects featured snippets and passage indexing.
10. Optimise images
Every image should have a descriptive alt attribute - not "image123.jpg" but "Nginx configuration file showing fastcgi_cache block". Alt text is the primary signal for image search and is used by screen readers.
Also:
- Use WebP format where possible (Imagify, ShortPixel, or Cloudflare Polish handle conversion)
- Set explicit width and height attributes on images to prevent layout shift (affects CLS score)
- Lazy-load below-the-fold images (
loading="lazy")
11. Optimise internal linking
Every new post should link to at least 2-3 relevant existing posts. Internal links:
- Pass PageRank between pages
- Help Google understand site structure and topic relationships
- Keep users on the site longer (improves engagement signals)
Use descriptive anchor text. "Click here" and "read more" are wasted opportunities. "How to configure FastCGI cache in Nginx" tells Google exactly what the linked page is about.
12. Check for duplicate content
The most common WordPress duplicate content issues:
- Tag archives duplicating category archive content
- Paginated archives without proper rel=prev/next handling
- WWW vs non-WWW - both versions accessible (fix with 301)
- Trailing slash inconsistency -
/page/and/pageboth loading content - Printer-friendly pages generated by some plugins
Add noindex to tag archives if they have low-quality content:
// In functions.php
add_action( 'wp_head', function() {
if ( is_tag() ) {
echo '<meta name="robots" content="noindex, follow">';
}
});
Core Web Vitals
13. Measure your current scores
Use Google PageSpeed Insights (pagespeed.web.dev) on your most important pages - the homepage, a category archive, and a typical article. Note the Largest Contentful Paint (LCP), First Input Delay/Interaction to Next Paint (INP), and Cumulative Layout Shift (CLS) scores.
Target thresholds:
- LCP: under 2.5 seconds
- INP: under 200ms
- CLS: under 0.1
14. Fix LCP - typically the hero image
LCP is almost always caused by a large image or a render-blocking resource. The most common fix:
<!-- Add fetchpriority="high" to the above-the-fold hero image --> <img src="hero.webp" fetchpriority="high" loading="eager" alt="..." />
Also: serve the LCP image from the same origin (not a third-party CDN that adds a DNS lookup), and ensure it is properly compressed and in WebP format.
15. Fix CLS - explicit image dimensions
Layout shift happens when the browser does not know an element's size before it loads and the page jumps as it appears. Add explicit width and height to all images:
<img src="screenshot.webp" width="800" height="450" alt="..." />
WordPress automatically adds these attributes when you use the media library. Custom image output in themes and page builders often omits them.
16. Reduce render-blocking resources
CSS and JavaScript in the <head> block page rendering. Check the Opportunities section of PageSpeed Insights for "Eliminate render-blocking resources". Common fixes:
- Add
deferattribute to non-critical JS - Move Google Fonts to local hosting (reduces DNS lookups and eliminates render-blocking)
- Minify and combine CSS where possible (a caching plugin handles this)
Schema markup
17. Add Article schema to all blog posts
Most SEO plugins add basic Article schema automatically. Verify it is present using the Google Rich Results Test (search.google.com/test/rich-results).
For an agency blog, the most valuable schema types are:
Article/BlogPosting- for all blog contentHowTo- for step-by-step guidesFAQPage- for pages with question-and-answer formatBreadcrumbList- for breadcrumb navigation (helps SERP appearance)
18. Add LocalBusiness schema for agency sites
If the site represents a local business:
{
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "Your Agency Name",
"url": "https://yourdomain.com",
"telephone": "+44-XX-XXXX-XXXX",
"address": {
"@type": "PostalAddress",
"addressLocality": "London",
"addressCountry": "GB"
}
}
Ongoing maintenance
19. Track rankings weekly
Set up rank tracking in Ahrefs, SEMrush, or Google Search Console for your target keywords. Rankings fluctuate - the goal is the trend over 90 days, not day-to-day changes.
20. Update old content
Google favours fresh content. Posts that ranked well in 2023 can drop as newer content from competitors appears. Quarterly, identify your top-10 ranking posts, update statistics, add new sections, and re-publish with an updated date.
21. Monitor backlink profile
In Google Search Console > Links > Top linking sites, check for new links monthly. Organic backlinks from relevant sites boost rankings. Spam links (adult sites, gambling directories) can trigger manual penalties. Use the Disavow tool in Search Console only if you have strong evidence of a toxic link pattern - Google is generally good at ignoring low-quality links on its own.
22. Fix broken links
Use a plugin like Broken Link Checker or a monthly Screaming Frog crawl to find 404s. Broken internal links waste crawl budget and frustrate users. Redirect or fix them promptly.
Quick-reference: the non-negotiables
If you do nothing else on this list, do these six:
- Site is indexable and HTTPS is consistent
- SEO plugin installed and every page has a unique title/description
- XML sitemap submitted to Search Console
- LCP image has
fetchpriority="high"and is in WebP format - All images have descriptive alt text and explicit dimensions
- Internal linking strategy is active (every new post links to existing content)
Related reading
Frequently Asked Questions
What are the most important WordPress SEO settings to configure?
What technical SEO issues are most common on WordPress sites?
How do I fix Core Web Vitals on WordPress?
Does WordPress SEO require a plugin?
How often should I run a WordPress SEO audit?
// new_articles
Get notified when new guides drop
Practical WordPress guides from a working agency owner. No filler. Unsubscribe any time.
Was this article helpful?
Thanks for the feedback!