Comprehensive SEO analysis and audit tools for WordPress sites in Trellis/Bedrock environments. These tools help identify technical SEO issues, content gaps, and optimization opportunities.
This directory contains production-tested SEO utilities for:
- Page Structure Analysis - Navigation hierarchy, orphaned pages, duplicate content
- Redirect Chain Auditing - HTTP→HTTPS, www canonicalization, security headers
- Schema Markup Validation - JSON-LD presence and type detection
- Blog Content Audits - Categorization, featured images, content length analysis
wp-cli/seo/
├── page-audit.sh # Page structure, hierarchy, and orphan detection
├── redirect-audit.sh # Comprehensive redirect chain and security header testing
├── schema-audit.sh # Schema markup validation across key pages
├── blog-audit.sh # Blog content categorization and quality analysis
├── orphan-pages-audit.sh # Find pages not linked from navigation menus
├── orphan-links-audit.sh # Find pages nothing else links to in its content
└── README.md # This file
- WP-CLI installed (included with Trellis)
- WordPress site (Bedrock or traditional structure)
- SSH access to server (for remote operations)
- curl for HTTP-based audits
# Local development (from Bedrock site directory)
cd /srv/www/example.com/current
./wp-cli/seo/redirect-audit.sh --url https://example.com
# Remote via Trellis
ssh web@example.com "cd /srv/www/example.com/current && \
./wp-cli/seo/page-audit.sh"
# Run schema audit
./wp-cli/seo/schema-audit.sh https://example.comScript: page-audit.sh
Analyzes WordPress page structure including hierarchy, navigation menus, key business pages, and identifies potential orphaned pages.
- Export all published pages with metadata (ID, title, slug, dates, parent)
- Analyze navigation menu structure (main menu and submenus)
- Check for key business pages (home, about, contact, services, etc.)
- Identify service/portfolio subpages
- Export complete page hierarchy from database
- Detect duplicate page titles
- Generate comprehensive audit report
# Run from WordPress directory (Bedrock: web/wp parent)
cd /srv/www/example.com/current
./wp-cli/seo/page-audit.sh
# With custom output directory
OUTPUT_DIR="reports/seo" ./wp-cli/seo/page-audit.shaudits/page-audit-[date].csv- All published pages inventoryaudits/navigation-structure-[date].txt- Menu structure exportaudits/page-hierarchy-[date].txt- Database hierarchy query resultsaudits/duplicate-page-titles-[date].txt- Duplicate title detectionaudits/page-audit-report-[date].txt- Comprehensive report
- Page Inventory - Total published pages count
- Navigation Analysis - Menu items and structure
- Key Pages Check - Verifies existence of critical business pages
- Hierarchy Analysis - Parent-child relationships
- Duplicate Detection - Finds pages with identical titles
- Orphan Detection - Pages not in main navigation (basic check)
- Run monthly for proactive SEO monitoring
- Review orphaned pages report and add internal links
- Use duplicate title report to improve page uniqueness
- Verify all key business pages exist and are accessible
Script: redirect-audit.sh
Comprehensive testing of redirect chains, HTTP→HTTPS redirects, www canonicalization, and security headers.
- Test HTTPS pages for optimal 200 response with 0 redirects
- Verify HTTP→HTTPS 301 redirects
- Check www→non-www canonicalization
- Validate security headers (HSTS, CSP, X-Frame-Options, X-Content-Type-Options)
- Color-coded output for quick assessment
- Detailed markdown report generation
# Audit a single site
./wp-cli/seo/redirect-audit.sh --url https://example.com
# With verbose curl output
./wp-cli/seo/redirect-audit.sh --url https://example.com --verbose
# Test specific URLs
./wp-cli/seo/redirect-audit.sh --url https://example.com/about/ --url https://example.com/contact/
# Save report to custom location
REPORT_DIR="reports" ./wp-cli/seo/redirect-audit.sh --url https://example.com- HTTPS Pages Test - Should return 200 with 0 redirects (optimal)
- HTTP→HTTPS Redirect - Should be single 301 redirect
- WWW Canonicalization - Should redirect www to non-www with 301
- Security Headers - Checks for HSTS, CSP, X-Frame-Options, X-Content-Type-Options
- ✅ OPTIMAL - 200 status, 0 redirects
⚠️ ACCEPTABLE - 200 status, 1 redirect (should be fixed)- ❌ ISSUE - Multiple redirect chains or incorrect status
results/audits/redirect-audit-[timestamp].md- Detailed markdown report
- Run after any server configuration changes
- Test all key landing pages, not just homepage
- Fix any redirect chains (multiple 301/302 hops)
- Implement missing security headers
- Verify www canonicalization is consistent
Script: schema-audit.sh
Validates JSON-LD schema markup presence and types across key WordPress pages.
- Detect JSON-LD schema blocks in page HTML
- Identify specific schema types:
- Organization
- LocalBusiness
- Service
- Product
- WebSite
- BreadcrumbList
- Check key pages (homepage, services, contact, portfolio, about, shop)
- Generate summary report with recommendations
# Audit schema on a site
./wp-cli/seo/schema-audit.sh https://example.com
# With custom output directory
OUTPUT_DIR="reports/seo" ./wp-cli/seo/schema-audit.sh https://example.comaudits/schema-audit-[date].txt- Complete audit report
| Page Type | Recommended Schema |
|---|---|
| Homepage | Organization, WebSite |
| Services | Service, BreadcrumbList |
| Contact | LocalBusiness, Organization |
| Portfolio/Case Studies | Article, BreadcrumbList |
| Shop/Packages | Product, Offer |
- Implement Organization schema on homepage
- Add LocalBusiness schema to contact page
- Use Service schema on all service pages
- Validate schema with Google's tools
- Monitor Google Search Console for schema errors
Script: blog-audit.sh
Analyzes blog post content for categorization, quality metrics, and SEO opportunities.
- Export all published blog posts with metadata
- Analyze post categories and tags
- Identify SME-focused vs technical content
- Check for posts without featured images
- Detect thin content (< 800 words)
- Generate content gap analysis
# Run blog audit
cd /srv/www/example.com/current
./wp-cli/seo/blog-audit.sh
# With custom output directory
OUTPUT_DIR="reports/seo" ./wp-cli/seo/blog-audit.shaudits/blog-audit-[date].csv- All published posts inventoryaudits/category-audit-[date].csv- Category analysisaudits/thin-content-[date].txt- Posts needing content expansionaudits/blog-audit-report-[date].txt- Comprehensive report
- Total published posts and categories
- SME-focused content count (mentions of "SME", "small business", "case study")
- Technical content count (mentions of "Trellis", "Sage", "Bedrock")
- Posts without featured images
- Posts with thin content (< 800 words)
- Maintain balance between SME-focused and technical content
- Add featured images to all posts
- Expand thin content posts to 800+ words
- Organize categories for better user experience
- Consider separating technical content to developer-focused site
Script: orphan-pages-audit.sh
Identifies pages that exist in WordPress but are not linked from navigation menus.
- Export all published pages
- Extract menu item URLs from navigation menus
- Compare pages against menu URLs
- Generate report of potential orphaned pages
# Run orphan pages audit
cd /srv/www/example.com/current
./wp-cli/seo/orphan-pages-audit.shThis script only looks at navigation menus. For the in-content view — pages
nothing else links to — run orphan-links-audit.sh (section 6) alongside it.
For a full external crawl, Screaming Frog SEO Spider, Ahrefs Site Audit, or
Sitebulb still go further than either script.
audits/orphaned-pages-[date].csv- Potential orphaned pages listaudits/menu-urls-[date].txt- URLs found in navigation
- Add internal links to important pages not in navigation
- Consider creating a sitemap page
- Use breadcrumb navigation
- Review and update navigation structure regularly
Script: orphan-links-audit.sh
Identifies published posts and pages that no other content links to. This is
the inbound-link sibling of orphan-pages-audit.sh — the two answer different
questions and are both worth running. A page can sit in the nav and still have
zero in-content links, or be linked from a dozen posts while absent from every
menu.
- Single SQL query — no crawl, no external tool
- Counts inbound references per published post/page, keeps the zeroes
- Runs locally or over SSH against production
- CSV export with ID, title, type, date, and URL
# Against production over SSH
./wp-cli/seo/orphan-links-audit.sh --host web@example.com
# Locally, from a Bedrock site directory
cd /srv/www/example.com/current
./wp-cli/seo/orphan-links-audit.sh --path web/wp --output reports/seoLink detection is a substring match of each page's slug against other published
post_content. A slug that appears as plain text counts as a link, and a page
linked only by ID (or by a slug-less shortlink) reads as orphaned. Treat the
output as a shortlist to review, not a verdict.
audits/orphan-links-[timestamp].csv- Pages with zero inbound internal links
- Work the list newest-first — recent posts are the ones most likely never linked
- Add links from topically related posts, not from a generic index page
- Re-run after a linking pass to confirm the count dropped
All SEO tools work seamlessly with Trellis:
# SSH into Vagrant VM
trellis vm shell
# Navigate to site
cd /srv/www/example.com/current
# Run SEO audits
./wp-cli/seo/redirect-audit.sh --url https://example.test
./wp-cli/seo/page-audit.sh# Direct SSH
ssh web@example.com "cd /srv/www/example.com/current && \
./wp-cli/seo/schema-audit.sh https://example.com"
# Copy script and run
scp wp-cli/seo/blog-audit.sh web@example.com:/srv/www/example.com/current/
ssh web@example.com "cd /srv/www/example.com/current && \
chmod +x ./wp-cli/seo/blog-audit.sh && \
./wp-cli/seo/blog-audit.sh"Bedrock structure requires --path=web/wp for WP-CLI commands. All scripts in this directory handle this automatically when run from the Bedrock root (/srv/www/example.com/current/).
/srv/www/example.com/current/
├── web/
│ ├── wp/ ← WordPress core (--path=web/wp)
│ ├── app/
│ │ ├── uploads/
│ │ ├── themes/
│ │ └── plugins/
│ └── index.php
├── composer.json
└── .env
| Audit Type | Frequency | Notes |
|---|---|---|
| Redirect Audit | Weekly | After any server config changes |
| Schema Audit | Monthly | Or after theme/plugin updates |
| Page Structure | Quarterly | Or after major content changes |
| Blog Content | Quarterly | Review content gaps |
| Orphan Pages | Quarterly | Use Screaming Frog for comprehensive check |
- Backup Database - For write operations (bulk-alt-text)
- Check Server Load - Some audits make many requests
- Verify WP-CLI Access - Test with
wp --version - Test on Staging First - For new audits, verify on staging
- Review Reports - All scripts generate detailed output files
- Prioritize Issues - Focus on high-impact problems first
- Track Changes - Document fixes and re-audit
- Set Up Monitoring - Automate regular checks where possible
-
WP-CLI not found
- Ensure WP-CLI is installed:
wp --version - Trellis includes WP-CLI by default
- For Bedrock, use
--path=web/wp
- Ensure WP-CLI is installed:
-
Database connection error
- Check
.envfile credentials - Verify database exists
- Test:
wp db check --path=web/wp
- Check
-
Permission denied
- Ensure running as
webuser on remote servers - Check file ownership:
ls -la
- Ensure running as
-
No pages found
- Verify post_type and post_status filters
- Check if site has any published pages
-
curl not found
- Install curl:
apt-get install curlorbrew install curl
- Install curl:
- WP-CLI Documentation
- Trellis Documentation
- Bedrock Documentation
- Google SEO Starter Guide
- Schema.org Documentation
- Technical SEO Guide by Moz
When adding new SEO tools:
- Test in Trellis development environment
- Document all commands with examples
- Include troubleshooting section
- Provide both local and remote usage examples
- Consider security implications (read-only vs write operations)
- Follow existing documentation format
- Add to appropriate subdirectory README